Das Pub Quiz gestern hat Spass gemacht. Hoffentlich haben auch alle ein bisschen etwas dazugelernt.
Hier sind noch die Fragen und Antworten.
Ein grosses Danke an Olve Maudal. Von ihm sind einige der Fragen. Und ein weiteres Danke an bbv Software Services AG für Pizza und Bier.
Mittwoch, 14. Dezember 2016
Donnerstag, 24. November 2016
13. Dezember: C++ Pub Quiz
Zum Abschluss des Jahres organisieren wir mal wieder ein C++ Pub Quiz.
Damit wir Energie haben uns an den Problemen den Kopf zu zerbrechen organisieren wir etwas zu Essen und zu Trinken.
bbv Software Services AG, Blumenrain 10, Luzern, 1. Stock
Di 13.12.2016, 19 - 21 Uhr (Anschliessend Apero)
Wir freuen uns auf dich.
Damit wir Energie haben uns an den Problemen den Kopf zu zerbrechen organisieren wir etwas zu Essen und zu Trinken.
Ort
Datum
Mitbringen
- Dein gesamtes C++ Wissen, du wirst es brauchen können
Anmeldung
Erfolgt über die Veranstaltung unserer Xing Gruppe C++ Usergroup Zentralschweiz, über den Meetup Event oder über das Kontaktformular rechts.Wir freuen uns auf dich.
Dienstag, 1. November 2016
14. Nov.:C++ Coding Dojo
Da man nie genug TDD (Test-Driven Development) und Pair-Programming
Skills trainieren kann, kommen wir auch im November zusammen um im
lockeren Rahmen zu üben und uns auszutauschen.
bbv Software Services AG, Blumenrain 10, Luzern, 1. Stock
Mo 14.11.2016, 19 - 21 Uhr (Anschliessend Apero)
Wir freuen uns auf dich.
Agenda
- Einführung Coding Dojo, TDD und Pair-Programming wenn nötig
- Paarweise TDD mit googletest üben
- Präsentation und Diskussion der Vorgehen
- Verlosung von Sponsoren "Goodies"
- Apero
Ort
Datum
Mitbringen
- Eigener netzwerkfähiger Notebook mit installiertem Browser. Es ist keine IDE und C++ Toolchain nötig. Wir programmieren im Browser.
- Spass, Mut und Enthusiasmus
Anmeldung
Erfolgt über die Veranstaltung unserer Xing Gruppe C++ Usergroup Zentralschweiz, über den Meetup Event oder über das Kontaktformular rechts.Wir freuen uns auf dich.
Samstag, 24. September 2016
Coding Dojo: 11. Oktober
Nach einigen Vorträgen, wollen wir mal wieder zusammenkommen um
gemeinsam in einer lockeren Atmosphäre an unseren TDD (Test-Driven
Development) und Pair-Programming Skills zu arbeiten.
bbv Software Services AG, Blumenrain 10, Luzern, 1. Stock
Di 11.10.2016, 19 - 21 Uhr (Anschliessend Apero)
Wir freuen uns auf dich.
Agenda
- Einführung Coding Dojo, TDD und Pair-Programming wenn nötig
- Paarweise TDD mit googletest üben
- Präsentation und Diskussion der Vorgehen
- Verlosung von Sponsoren "Goodies"
- Apero
Ort
Datum
Mitbringen
- Eigener netzwerkfähiger Notebook mit installiertem Browser. Es ist keine IDE und C++ Toolchain nötig. Wir programmieren im Browser.
- Spass, Mut und Enthusiasmus
Anmeldung
Erfolgt über die Veranstaltung unserer Xing Gruppe C++ Usergroup Zentralschweiz, über den Meetup Event oder über das Kontaktformular rechts.Wir freuen uns auf dich.
Freitag, 16. September 2016
Cross-Plattform Entwicklung mit dem C++Builder von Embarcadero
Am Montag präsentierte uns Christoph Schneider einen interessanten Vortrag über den C++Builder von Embarcadero und zeigte uns in einer Kurzdemo wie man damit in kurzer Zeit eine einfache App entwickeln kann, die sowohl auf Windows, Mac OS X, Android und iOS läuft.
Die Vortragsunterlagen findet ihr unter https://goo.gl/ZYmBtm
Das Skript zur Demo findet ihr unter https://goo.gl/6LHCwG
Christoph könnt ihr über sein Xing Profil, sein Google+ Profile oder über seine Firma Schneider Infosystems AG erreichen.
Vielen Dank nochmals an Christoph für den gelungen und interessanten Abend
Die Vortragsunterlagen findet ihr unter https://goo.gl/ZYmBtm
Das Skript zur Demo findet ihr unter https://goo.gl/6LHCwG
Christoph könnt ihr über sein Xing Profil, sein Google+ Profile oder über seine Firma Schneider Infosystems AG erreichen.
Vielen Dank nochmals an Christoph für den gelungen und interessanten Abend
Sonntag, 7. August 2016
12. September: Cross-Plattform Entwicklung mit dem C++Builder von Embarcadero
Am ersten C++ Usergroup Meeting nach den Ferien wird uns Christoph Schneider eine Möglichkeit zur Cross-Platform Entwicklung mit C++ vorstellen.
bbv Software Services AG, Blumenrain 10, Luzern, 1. Stock
Mo 12.9.2016, 19 - 21 Uhr (Anschliessend Apero)
Wir freuen uns auf dich.
Abstrakt:
Der
C++Builder von Embarcadero ermöglicht native Cross-Plattform
Entwicklung
für Android, IOS, Windows 32/64 und MacOS. Das plattformunabhängige
FireMonkey-Framework eignet sich aus Sicht des Referenten bestens um
moderne Apps zu erstellen, die auf unterschiedlichen
Display-Formfaktoren skalieren. Im Rahmen dieser Session wird anhand
einer Demo-App gezeigt, wie ein Single-Source-Projekt für
unterschiedliche Geräte und Betriebssysteme entwickelt wird. Neben dem
GUI-Design werden Themen wie Cross-Debugging und Auslagerung von
zeitintensiven Funktionen in Background-Threads gezeigt. Weitergehende
Themen wie 3D-GUI, Einsatz von lokalen und Remote-Datenbanken und
Rest-Services wie auch die Ansteuerung von Geräte-Sensoren und
Kommunikations-Kanale wie Bluetooth/BluetoothLE können im Rahmen dieser
Session nur gestreift werden.
Agenda
- Einführung
- "C++ Cross-Plattform Entwicklung mit dem C++Builder von Embarcadero" von Christoph Schneider
- Verlosung von Sponsoren Goodies
- Apéro
Ort
Datum
Anmeldung
Erfolgt über die Veranstaltung unserer Xing Gruppe C++ Usergroup Zentralschweiz, über den Meetup Event oder über das Kontaktformular rechts.Wir freuen uns auf dich.
Dienstag, 14. Juni 2016
Handouts "Templates für Normalsterbliche"
Die Präsentation zu Adrian Imbodens Vortrag "Templates für Normalsterbliche" vom 9. Mai findet ihr hier.
Montag, 23. Mai 2016
Abgesagt: 7. Juni: Coding Dojo
Mangels Teilnehmer müssen wir dieses Coding Dojo leider Absagen.
Danke für das Verständnis und bis im September.
Im letzten Coding Dojo vor der Sommerpause üben wir an einem einfachen Code Kata TDD und Pair-Programming mit Googletest / Googlemock.
Agenda
- Einführung Coding Dojo, TDD und Pair-Programming wenn nötig
- Paarweise TDD mit googletest üben
- Präsentation und Diskussion der Vorgehen
- Verlosung von Sponsoren "Goodies"
- Apero
Ort
Datum
Mitbringen
- Eigener netzwerkfähiger Notebook mit installiertem Browser. Es ist keine IDE und C++ Toolchain nötig. Wir programmieren im Browser.
- Spass, Mut und Enthusiasmus
Anmeldung
Erfolgt über die Veranstaltung unserer Xing Gruppe C++ Usergroup Zentralschweiz, über den Meetup Event oder über das Kontaktformular rechts.Wir freuen uns auf dich.
Mittwoch, 13. April 2016
Handout: "How to Apply Engineering Practices to Embedded Software Development"
Ein Handout zum Vortrag "How to Apply Engineering Practices to Embedded Software Development" vom 5. April findet ihr hier.
Montag, 11. April 2016
9. Mai: C++ Templates für Normalsterbliche
Adrian Imboden wird uns in seinem Vortrag C++ Templates näherbringen und auf folgende Fragen eingehen:
bbv Software Services AG, Blumenrain 10, Luzern, 1. Stock
Mo 9.5.2016, 19 - 21 Uhr (Anschliessend Apero)
Wir freuen uns auf dich.
- Was sind Templates
- Wofür sind Templates gut
- Wie kann ich sie verwenden
Agenda
- Einführung
- "C++ Templates für Normalsterbliche" von Adrian Imboden
- Verlosung von Sponsoren Goodies
- Apéro
Ort
Datum
Anmeldung
Erfolgt über die Veranstaltung unserer Xing Gruppe C++ Usergroup Zentralschweiz, über den Meetup Event oder über das Kontaktformular rechts.Wir freuen uns auf dich.
Mittwoch, 23. März 2016
5. April: How to Apply Engineering Practices to Embedded Software Development
Raphael Meyer wird uns in seinem Vortrag ein "Walking Skeleton" für
Embedded Software Projekte vorstellen und diverse "Engineering
Practices" näherbringen. Der folgende Abstrakt ist in Englisch der
Vortrag wird aber in Deutsch oder Englisch gehalten:
How to Apply Engineering Practices to Embedded Software Development
A steadily increasing number of things for everyday use have more and more software embedded. If that software is not carefully crafted then we may be facing a dystopian future where we’ll be enslaved by dysfunctional technology.
bbv Software Services AG, Blumenrain 10, Luzern, 1. Stock
Di 5.4.2016, 19 - 21 Uhr (Anschliessend Apero)
Wir freuen uns auf dich.
How to Apply Engineering Practices to Embedded Software Development
A steadily increasing number of things for everyday use have more and more software embedded. If that software is not carefully crafted then we may be facing a dystopian future where we’ll be enslaved by dysfunctional technology.
Over the last few decades various engineering practices have been introduced to support the development of
functional software. Unfortunately the field of embedded software struggles with applying these practices.
In this session I demonstrate an example of a walking skeleton for an embedded software project. By studying
the example we discuss some of the engineering practices and we will see that these can be applied to
embedded software development as well.
We will talk a lot about growing software guided by tests. Other topics include for example how to maintain
a cross toolchain for reproducible builds.
Agenda
- How to Apply Engineering Practices to Embedded Software Development (Deutsch oder Englisch)
- Verlosung von Sponsoren Goodies
- Apéro
Ort
Datum
Anmeldung
Erfolgt über die Veranstaltung unserer Xing Gruppe C++ Usergroup Zentralschweiz, über den Meetup Event oder über das Kontaktformular rechts.Wir freuen uns auf dich.
Montag, 29. Februar 2016
14. März: Test-Driven-Development mit C++
Als Vorbereitung für die kommenden Coding Dojos werden wir dieses Mal
eine etwas tiefere Einführung in Test-Driven-Development (TDD) geben und
Beispiele und Übungen mit Googletest und Googlemock machen.
bbv Software Services AG, Blumenrain 10, Luzern, 1. Stock
Mo 14.3.2016, 19 - 21 Uhr (Anschliessend Apero)
Es sind alle herzlich Willkommen die gerne mit C++ programmieren. Egal ob Anfänger oder Experte.
Wir freuen uns auf dich.
Wir freuen uns auf dich.
Agenda
- Einführung in Unittests, TDD und Test Doubles
- Übungen (Coding Dojo) wenn wir noch Zeit haben
- Verlosung von Sponsoren Goodies
- Apéro
Ort
Datum
Mitbringen
- Notebook mit Browser
- Spass, Mut und Enthusiasmus
Es sind alle herzlich Willkommen die gerne mit C++ programmieren. Egal ob Anfänger oder Experte.
Wir freuen uns auf dich.
Anmeldung
Erfolgt über die Veranstaltung unserer Xing Gruppe C++ Usergroup Zentralschweiz, über den Meetup Event oder über das Kontaktformular rechts.Wir freuen uns auf dich.
Montag, 22. Februar 2016
C++ Idioms
Am letzten Meeting haben wir uns ein paar C++ Idiome angeschaut. Hier eine Zusammenfassung der behandelten Idiome.
Die Lösungen zu den Übungen findet ihr sowohl unten in den Beispielen als auch unter github.com/meshell/Cpp-Idioms.
Idioms are similar to patterns but usually smaller, programming language specific and do cover algorithms and concepts rather than design issues.
When a base class is intended for polymorphic use, its destructor may have to be declared public and virtual. This blocks implicit moves (and deprecates implicit copies), and so the special member functions have to be declared as defaulted.
Die Lösungen zu den Übungen findet ihr sowohl unten in den Beispielen als auch unter github.com/meshell/Cpp-Idioms.
C++ Idioms
A programming idiom is a recurring construct in a programming language. It is important to know the idioms associated with a programming language and how to use them for gaining fluency in that language.Idioms are similar to patterns but usually smaller, programming language specific and do cover algorithms and concepts rather than design issues.
RAII
Intent
- To guarantee release of resource(s) at the end of a scope
- To provide basic exception safety guarantee
Description
Resource Acquisition Is Initialization (RAII), is a C++ programming technique which binds the life cycle of a resource (allocated memory, open socket, open file, locked mutex, database connection—anything that exists in limited supply) to the lifetime of an object with automatic storage duration. RAII guarantees that the resource is available to any function that may access the object (resource availability is a class invariant). It also guarantees that all resources are released when their controlling objects go out of scope, in reverse order of acquisition. Likewise, if resource acquisition fails (the constructor exits with an exception), all resources acquired by every fully-constructed member and base subobject are released in reverse order of initialization. This leverages the core language features (object lifetime, scope exit, order of initialization and stack unwinding) to eliminate resource leaks and guarantee exception safety. Another name for this technique is Scope-Bound Resource Management (SBRM).Example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <cstdio> | |
#include <cstdlib> | |
#include <memory> | |
int main() | |
{ | |
auto file_open = [](const char* filename, const char* mode) -> FILE* | |
{ | |
return std::fopen(filename, mode); | |
}; | |
auto file_deleter=[](FILE* file) { | |
std::puts("Close file\n"); | |
std::fclose(file); | |
}; | |
// Using a unique pointer and custom deleter (lamda) | |
std::unique_ptr<FILE, decltype(file_deleter)> fp{file_open("test.txt", "r"), | |
file_deleter}; | |
if(!fp) { | |
std::perror("File opening failed"); | |
return EXIT_FAILURE; | |
} | |
int c{}; | |
while ((c = std::fgetc(fp.get())) != EOF) { | |
std::putchar(c); | |
} | |
if (std::ferror(fp.get())) { | |
std::puts("I/O error when reading"); | |
return EXIT_FAILURE; | |
} else if (std::feof(fp.get())) { | |
std::puts("End of file reached successfully"); | |
} | |
} |
References
Smart pointer
Intent
- Avoid manual memory management to improve safety and reduce bugs and memory leaks.
- Declare ownership explicitly
Description
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// unique object ownership | |
auto unique = std::unique_ptr<widget>(new widget()); | |
auto unique = std::make_unique<widget>(); | |
// shared object ownership | |
auto shared = std::make_shared<widget>(); | |
// weak reference to an object managed by std::shared_ptr | |
std::weak_ptr<widget> weak = shared; | |
auto shared_tmp = weak.lock(); |
Example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef DOUBLE_LINKED_LIST_H | |
#define DOUBLE_LINKED_LIST_H | |
#include <vector> | |
#include <memory> | |
#include <iostream> | |
template<typename T> | |
struct Node { | |
explicit Node(T val) | |
: value{val} | |
{} | |
~Node() { | |
std::cout << "Node " << value << " destroyed\n"; | |
} | |
Node(const Node&) = default; | |
Node(Node&&) = default; | |
Node& operator=(const Node&) = default; | |
Node& operator=(Node&&) = default; | |
T value; | |
std::shared_ptr<Node> next = nullptr; | |
std::weak_ptr<Node> previous; // using a shared_ptr would introduce circular dependencies | |
}; | |
template<typename T> | |
class DoubleLinkedList { | |
public: | |
void push_front (T x); | |
void push_back (T x); | |
std::vector<T> get_nodes_forward() ; | |
std::vector<T> get_nodes_reverse (); | |
private: | |
std::shared_ptr<Node<T>> front = nullptr; | |
std::shared_ptr<Node<T>> back = nullptr; | |
}; | |
template<typename T> | |
void DoubleLinkedList<T>::push_front(T x) | |
{ | |
const auto n = std::make_shared<Node<T>>(x); | |
if( not front) { | |
front = n; | |
back = n; | |
} else { | |
front->previous = n; | |
n->next = front; | |
front = n; | |
} | |
} | |
template<typename T> | |
void DoubleLinkedList<T>::push_back(T x) | |
{ | |
const auto n = std::make_shared<Node<T>>(x); | |
if( not back) { | |
front = n; | |
back = n; | |
} else { | |
back->next = n; | |
n->previous = back; | |
back = n; | |
} | |
} | |
template<typename T> | |
std::vector<T> DoubleLinkedList<T>::get_nodes_forward() | |
{ | |
auto temp = front; | |
std::vector<T> out; | |
while(temp) { | |
out.push_back(temp->value); | |
temp = temp->next; | |
} | |
return out; | |
} | |
template<typename T> | |
std::vector<T> DoubleLinkedList<T>::get_nodes_reverse() | |
{ | |
auto temp = back; | |
std::vector<T> out; | |
while(temp) { | |
out.push_back(temp->value); | |
temp = temp->previous.lock(); | |
} | |
return out; | |
} | |
#endif |
References
- cppreference.com std::unique_ptr
- cppreference.com std::smart_ptr
- cppreference.com std::weak_ptr
- Herb Sutter's GotW #90
- C++ Samples: Unique ownership
- Item 18-22 of "Effective Modern C++" by Scott Meyers, O'Reilly, 2014
PIMPL
Intent
- Remove compilation dependencies on internal class implementations and improve compile times.
Description
When anything in a header file class definition changes, all users of that class must be recompiled – even if the only change was to the private class members that the users of the class cannot even access. The PIMPL idiom hides private members from any users of the header file, allowing these internal details to change without requiring recompilation of the client code.Example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "pimpl.h" | |
#include <iostream> | |
#include <string> | |
#include <vector> | |
class foo::impl { | |
public: | |
void initialize() { | |
member1 = "Hello"; | |
member2 = "World"; | |
member3 = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1 }; | |
} | |
void print() { | |
print_member3(); | |
std::cout << member1 << member2 << std::endl; | |
} | |
void print_member3() { | |
auto it = std::begin(member3); | |
do { | |
std::cout << (*it); | |
if(++it != std::end(member3)) { | |
std::cout << ", "; | |
} | |
} while (it != std::end(member3)); | |
std::cout << "..." << std::endl; | |
} | |
private: | |
std::string member1; | |
std::string member2; | |
std::vector<int> member3; | |
}; | |
foo::foo(): pimpl(std::make_unique<impl>()) { | |
pimpl->initialize(); | |
} | |
foo::~foo() = default; | |
foo::foo(const foo& rhs) : pimpl(std::make_unique<impl>(*rhs.pimpl)) | |
{} | |
foo& foo::operator=(const foo& rhs) { | |
*pimpl = *rhs.pimpl; | |
return *this; | |
} | |
foo::foo(foo&&) = default; | |
foo& foo::operator=(foo&&) = default; | |
void foo::print() { | |
pimpl->print(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef PIMPL_H | |
#define PIMPL_H | |
#include <memory> | |
class foo | |
{ | |
public: | |
foo(); | |
void print(); | |
~foo(); | |
foo(const foo&); | |
foo& operator=(const foo&); | |
foo(foo&&); | |
foo& operator=(foo&&); | |
private: | |
class impl; | |
std::unique_ptr<impl> pimpl; | |
}; | |
#endif |
References
- Herb Sutter's GotW #100
- C++ Samples: PIMPL]
- Item 22 of "Effective Modern C++" by Scott Meyers, O'Reilly, 2014
Rule of Five
Intent
- Safely and efficiently implement RAII to encapsulate the management of dynamically allocated resources.
Description
The rule of five is a modern expansion of the rule of three. Firstly, the rule of three specifies that if a class implements any of the following functions, it should implement all of them:- copy constructor
- copy assignment operator
- destructor
- move constructor
- move assignment operator
Example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <cstring> | |
#include <iostream> | |
class foo | |
{ | |
public: | |
// Constructor | |
explicit foo(const char* arg) : cstring{new char[std::strlen(arg)+1]} | |
{ | |
std::strcpy(cstring, arg); | |
std::cout << "constructed\n"; | |
} | |
// Destructor | |
~foo() { | |
delete[] cstring; | |
std::cout << "destructed\n"; | |
} | |
// Copy constructor | |
foo(const foo& other) : cstring{new char[std::strlen(other.cstring) + 1]} | |
{ | |
std::strcpy(cstring, other.cstring); | |
std::cout << "copy constructed\n"; | |
} | |
// Move constructor | |
foo(foo&& other) noexcept : cstring{std::move(other.cstring)} | |
{ | |
other.cstring = nullptr; | |
std::cout << "move constructed\n"; | |
} | |
// Copy assignment | |
foo& operator=(const foo& other) { | |
foo tmp{other}; // re-use copy-constructor | |
*this = std::move(tmp); // re-use move-assignment | |
std::cout << "copy assigned\n"; | |
return *this; | |
} | |
// move assignment | |
foo& operator=(foo&& other) noexcept { | |
delete[] cstring; | |
cstring = std::move(other.cstring); | |
other.cstring = nullptr; | |
std::cout << "move assigned\n"; | |
return *this; | |
} | |
private: | |
char* cstring; // raw pointer used as a handle to a dynamically-allocated memory block | |
}; |
References
Copy & Swap
Intent
- To create an exception safe implementation of overloaded assignment operator.
Description
Copy assignment and move assignment operators can be expressed in terms of move constructor, destructor, and the swap() member function, if one is provided. For the move assignment operator this comes at the cost of one additional call to the move constructor , which is often acceptable.Example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <cstring> | |
#include <iostream> | |
class foo | |
{ | |
public: | |
explicit foo(const char* arg) : cstring{new char[std::strlen(arg)+1]} { | |
std::strcpy(cstring, arg); | |
} | |
~foo() { | |
delete[] cstring; | |
} | |
foo(const foo& other) : cstring{new char[std::strlen(other.cstring) + 1]} { | |
std::strcpy(cstring, other.cstring); | |
} | |
foo(foo&& other) noexcept : cstring{other.cstring} { | |
other.cstring = nullptr; | |
} | |
// Copy assignment and Move assignment | |
foo& operator=(foo other) // pass by value | |
{ | |
std::swap(cstring, other.cstring); | |
return *this; | |
} | |
private: | |
char* cstring; | |
}; |
References
- cppreference.com Copy assignment operator
- cppreference.com Move assignment operator
- More C++ Idioms wikibook: Copy and swap
Rule of Zero
Intent
- Utilise the value semantics of existing types to avoid having to implement custom copy and move operations.
Description
Classes that have custom destructors, copy/move constructors or copy/move assignment operators should deal exclusively with ownership and support the appropriate copy/move semantics. Other classes therefore should not have custom destructors, copy/move constructors or copy/move assignment operators.Example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <string> | |
class foo { | |
public: | |
// Constructor | |
foo(const std::string& arg) : cppstring(arg) {} | |
private: | |
std::string cppstring | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class base { | |
public: | |
virtual ~base() = default; | |
base(const base&) = default; | |
base(base&&) = default; | |
base& operator=(const base&) = default; | |
base& operator=(base&&) = default; | |
}; |
References
Erase-Remove
Intent
- Eliminate elements from a STL container.
Example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <vector> | |
#include <algorithm> | |
int main() { | |
std::vector<int> v = {1, 2, 3, 4, 2, 5, 2, 6}; | |
v.erase(std::remove(std::begin(v), | |
std::end(v), | |
2), | |
std::end(v)); | |
// using a custom predicate | |
v.erase(std::remove_if(std::begin(v), | |
std::end(v), | |
[](int i) { | |
return i%2 == 0; | |
}), | |
std::end(v)); | |
} |
References
- More C++ Idioms wikibook: Erase-Remove
- C++ Samples: Remove elements from a container
- cppreference.com
Type Generator
Intent
- Simplify creation of complex template-based types
- Synthesize a new type or types based on template argument(s)
- Localize default policies when policy-based class design is used
Example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Until C++11 | |
template<class T> | |
struct p | |
{ | |
typedef T* Type; | |
}; | |
p<float>::Type y; // y is of type float* | |
// Since C++11: alias template | |
template<class T> | |
using ptr = T*; | |
ptr<int> x; // x is of type int* |
References
Overriding Virtual Functions
Intent
- Override a virtual function of a base class in a safe manner.
Description
Overriding virtual functions may cause problems, for example during refactoring, when renaming a (non pure) virtual base method. Because the compiler cannot warn you that you forgot to replace the overridden methods in the specialized classes you may actually declare a new method in the specialized class instead of overriding one. Therefore as a guideline when using C++11 or higher is: Always write override when you intend to override a virtual function.Example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
struct base { | |
virtual std::string name() { return "default"; } | |
}; | |
struct derived : public base { | |
// compile error: 'std::string derived::mame()' marked 'override', but does not override | |
std::string mame() override { return "derived!" } | |
}; |
References
Prohibit derivation
Intent
- Prohibit to further override a virtual function.
- Prohibit a class to have further-derived classes.
Description
Writing final makes a virtual function no longer overrideable in further-derived classes, or a class no longer permitted to have further-derived classes.Example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
struct base { | |
virtual std::string name() { return "default"; } | |
virtual void foo() final { } | |
}; | |
struct derived final: public base { | |
std::string name() override { return "derived!" } | |
// compile error: overriding final function 'virtual void base::foo()' | |
void foo() override { } | |
}; | |
// compile error: cannot derive from 'final' base 'derived' | |
struct further_derived : public derived { | |
std::string name() override { return "further derived!" } | |
}; |
References
Shrink to fit
Intent
- Minimize the capacity of a container just enough to hold existing range.
Description
Since C++11 the Shrink-to-fit idiom is directly supported.Example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <vector> | |
// Until C++11 | |
std::vector<int> v; | |
//v is swapped with its temporary copy, which is capacity optimal | |
std::vector<int>(v.begin(), v.end()).swap(v); | |
// Since C++11 | |
std::vector<int> v2; | |
v2.shrink_to_fit(); |
References
Range-based for loop
Intent
- Executes a for loop over a range of values, such as all elements in a container.
Description
Since C++11 the Range-based for loop is used as a more readable equivalent to the traditional for loop.Example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <vector> | |
int main() { | |
std::vector<int> v = {0, 1, 2, 3, 4, 5}; | |
for(const auto& i : v) { | |
std::cout << i << ' '; | |
} | |
std::cout << '\n'; | |
int a[] = {0, 1, 2, 3, 4, 5}; | |
for(const auto& n : a) { | |
std::cout << n << ' '; | |
} | |
std::cout << '\n'; | |
} |
References
AAA (Almost always auto)
Intent
- Specify that the type of the variable that is being declared will be automatically deduced from its initializer.
- Write code against interfaces, not implementations.
- Prevent correctness and performance issues that can bedevil manual type declarations.
Description
When declaring variables in block scope, in namespace scope, in init statements of for loops, etc, the keyword auto may be used as the type specifier. Once the type of the initializer has been determined, the compiler determines the type that will replace the keyword auto using the rules for template argument deduction from a function call.Examples
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Classic C++ declaration order // Modern C++ style | |
const char* s = "Hello"; auto s = "Hello"; | |
widget w = get_widget(); auto w = get_widget(); | |
employee e{ empid }; auto e = employee{ empid }; | |
widget w{ 12, 34 }; auto w = widget{ 12, 34 }; | |
unique_ptr<widget> w auto w = make_unique<widget>(); | |
= make_unique<widget>(); | |
int x = 42; auto x = 42; | |
float x = 42.; auto x = 42.f; | |
unsigned long x = 42; auto x = 42ul; | |
std::string x = "42"; auto x = "42"s; // C++14 | |
chrono::nanoseconds x{ 42 }; auto x = 42ns; // C++14 |
References
- cppreference.com: auto
- Herb Sutter's GotW #94
- Item 5 of "Effective Modern C++" by Scott Meyers, O'Reilly, 2014
Use Standard Library Algorithms
Intent
- Use the standard library algorithms rather than reinventing the wheel.
Examples
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <algorithm> | |
#if __cplusplus > 201103L | |
// for C++14 use | |
using std::cbegin; | |
using std::cend; | |
#else | |
// C++11 does not implement non-member version of cbegin and cend. | |
// Therefor for a C++11 only compiler use | |
template<class C> | |
auto cbegin(const C& container)->decltype(std::begin(container)) { | |
// invoking the non-member begin function on a const container yields a const-iterator. | |
return std::begin(container); | |
} | |
template<class C> | |
auto cend(const C& container)->decltype(std::end(container)) { | |
// invoking the non-member end function on a const container yields a const-iterator. | |
return std::end(container); | |
} | |
#endif | |
template<typename C> | |
void sort_ascending(C& container) { | |
using std::begin; | |
using std::end; | |
std::sort(std::begin(container), std::end(container)); | |
} | |
template<typename C> | |
void sort_descending(C& container) { | |
using std::begin; | |
using std::end; | |
std::sort(std::begin(container), std::end(container), std::greater<typename C::value_type>()); | |
} | |
template<class C> | |
void sort_and_remove_duplicates(C& container) { | |
using std::begin; | |
using std::end; | |
std::sort(begin(container), end(container)); | |
container.erase(std::unique(begin(container), end(container)), end(container)); | |
} | |
template<class C> | |
bool has_even_elements(C& container) { | |
return std::any_of(cbegin(container), cend(container), [](int i){ return i % 2 == 0; })); | |
} |
References
constexpr
Intent
- To have an integral value that is const and known during compilation.
- To place values in read-only memory.
Example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <array> | |
#include <iostream> | |
#if __cplusplus > 201103L | |
constexpr int pow(int base, int exp) noexcept | |
{ | |
auto result = 1; | |
for (int i = 0; i < exp; ++ i) { | |
result *= base; | |
} | |
return result; | |
} | |
#else | |
constexpr int pow(int base, int exp) noexcept | |
{ | |
return (exp == 0 ? 1 : base * pow(base, exp -1)); | |
} | |
#endif | |
int main() | |
{ | |
// We need to store all possible combinations of n values with 3 states | |
constexpr auto n = 5; // n is 5 | |
std::array<int, pow(3, n)> results; | |
std::cout << results.size() << '\n'; | |
} |
References
- Item 15 of "Effective Modern C++" by Scott Meyers, O'Reilly, 2014
User-defined literals
Intent
- Produce objects of user-defined type by defining a user-defined suffix.
Example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <chrono> | |
// used as conversion | |
constexpr long double operator"" _m ( long double m ) { | |
return m; | |
} | |
constexpr long double operator"" _km ( long double km ) { | |
return km * 1000.0_m; | |
} | |
constexpr long double operator"" _nmi ( long double nmi ) { | |
return nmi * 1852.0_m; | |
} | |
// used for side-effects | |
void operator"" _print ( const char* str ) { | |
std::cout << str << '\n'; | |
} | |
int main() { | |
const double distance_sea = 150.0_nmi; | |
const double distance = distance_sea / 1.0_km; | |
std::cout << std::fixed << distance_sea << "m\n"; | |
std::cout << std::fixed << distance << "km\n"; | |
0x123ABC_print; | |
#if __cplusplus > 201103L | |
// With C++14 some literal operators are defined in the standard library | |
using namespace std::chrono_literals; | |
auto d1 = 250ns; | |
std::chrono::nanoseconds d2 = 1us; | |
std::cout << "250ns = " << d1.count() << " nanoseconds\n" | |
<< "1us = " << d2.count() << " nanoseconds\n"; | |
#endif | |
} |
References
Static Assertion
Intent
- Perform compile-time assertion checking.
Example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <type_traits> | |
template <class T> | |
void swap(T& a, T& b) { | |
static_assert(std::is_copy_constructible<T>::value, | |
"Swap requires copying"); | |
static_assert(std::is_nothrow_move_constructible<T>::value | |
&& std::is_nothrow_move_assignable<T>::value, | |
"Swap may throw"); | |
auto c = b; | |
b = a; | |
a = c; | |
} |
References
Placement Insert aka emplace
Intent
- Creating objects in place while inserting into a container.
- Enable insertion of elements that are not CopyConstructable.
Example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <string> | |
#include <vector> | |
struct Type | |
{ | |
Type(std::string, float) {}; | |
Type(Type const &) = delete; | |
Type(Type &&) = default; | |
}; | |
int main() | |
{ | |
std::vector<Type> values; | |
values.emplace_back("pi", 3.14); | |
} |
References
Samstag, 23. Januar 2016
C++11/14 Idioms: 15. Februar
Den beim letzen Event angekündigten Termin mussten wir leider nochmals
ändern. Am ersten Dienstag im Februar ist in Luzern mit der Fasnacht die
Hölle los und am zweiten Dienstag im Monat ist die .NET Usergroup in
der bbv in Luzern. Wir treffen uns deshalb ausnahmsweise nochmals am
Montag.
Wir werden diesmal ein paar C++ Idiome betrachten, Üben und Diskutieren. Der Fokus ist dabei "Modernes C++", d.h. C++11/14
bbv Software Services AG, Blumenrain 10, Luzern, 1. Stock
Mo 15.2.2016, 19 - 21 Uhr (Anschliessend Apero)
Es sind alle herzlich Willkommen die gerne mit C++ programmieren. Egal ob Anfänger oder Experte.
Wir freuen uns auf dich.
Wir freuen uns auf dich.
Wir werden diesmal ein paar C++ Idiome betrachten, Üben und Diskutieren. Der Fokus ist dabei "Modernes C++", d.h. C++11/14
Agenda
- Präsentation und Üben von C++11/14 Idiomen
- Verlosung von Sponsoren Goodies
- Apéro
Ort
Datum
Mitbringen
- Notebook mit C++11/14 Compiler und IDE deiner Wahl
- Spass, Mut und Enthusiasmus
Es sind alle herzlich Willkommen die gerne mit C++ programmieren. Egal ob Anfänger oder Experte.
Wir freuen uns auf dich.
Anmeldung
Erfolgt über die Veranstaltung unserer Xing Gruppe C++ Usergroup Zentralschweiz, über den Meetup Event oder über das Kontaktformular rechts.Wir freuen uns auf dich.
Samstag, 2. Januar 2016
Coding Dojo: 11. Januar
Beim ersten Coding Dojo im Neuen Jahr versuchen wir eine neue Form.
Lasst Euch überraschen. Das Ziel ist wieder das Üben von
Pair-Programming und TDD mit Googletest/Googlmock.
bbv Software Services AG, Blumenrain 10, Luzern, 1. Stock
Mo 11.1.2016, 19 - 21 Uhr (Anschliessend Apero)
Wir freuen uns auf dich.
Agenda
- Einführung Coding Dojo, TDD und Pair-Programming nach Bedarf
- Coding Dojo
- Diskussion und Abschluss
- Apéro
Ort
Datum
Mitbringen
- Spass, Mut und Enthusiasmus
Anmeldung
Erfolgt über die Veranstaltung unserer Xing Gruppe C++ Usergroup Zentralschweiz, über den Meetup Event oder über das Kontaktformular rechts.Wir freuen uns auf dich.
Abonnieren
Posts (Atom)