├── .gitignore
├── README.md
├── TODO.md
└── src
├── Makefile
├── algorithms.cpp
├── aliastemplates.cpp
├── array.cpp
├── auto.cpp
├── chrono.cpp
├── constexpr.cpp
├── defaultdelete.cpp
├── defaultfunctiontemplates.cpp
├── delegation.cpp
├── enumeration.cpp
├── file.cpp
├── foreach.cpp
├── forwardlist.cpp
├── future.cpp
├── hashtable.cpp
├── initializer.cpp
├── lambda.cpp
├── literals.cpp
├── math.cpp
├── move.cpp
├── mutex.cpp
├── nullptr.cpp
├── overridefinal.cpp
├── random.cpp
├── referencewrapper.cpp
├── regex.cpp
├── rightbrackets.cpp
├── rvalues.cpp
├── smartpointer.cpp
├── staticassert.cpp
├── stringliterals.cpp
├── thread.cpp
├── tokens.cpp
├── trailingreturntype.cpp
├── trigraph.cpp
├── tuple.cpp
├── valarray.cpp
└── variadictemplates.cpp
/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !Makefile
3 | !README.md
4 | !TODO.md
5 | !src/
6 | !*.cpp
7 | !*.h
8 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | C++11 Snippets
2 | ==============
3 |
4 | Learn the new C++11 features by examples.
5 |
6 | Note: this repository is a few years old now and not really maintained anymore.
7 | My ongoing work on a C++14 repository is here: https://github.com/daniel-j-h/cpp14-snippets
8 |
9 |
10 | Description
11 | -----------
12 |
13 | Source for the references is the free [N3337](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf) working draft (pdf), dated 16 January 2012
14 |
15 |
16 | file | reference | description |
17 | algorithms.cpp | [algorithms] | algorithm on container, using lambda |
18 | aliastemplates.cpp | [temp.alias] | alias templates |
19 | array.cpp | [array] | constant size array container |
20 | auto.cpp | [dcl.spec.auto] | auto type-specifier for variables |
21 | chrono.cpp | [time.syn] | time utilities |
22 | constexpr.cpp | [expr.const] | compile time and run time const |
23 | defaultdelete.cpp | [dcl.fct.def.general] | defaulted and deleted definition |
24 | defaultfunctiontemplates.cpp | [temp.param] | default arguments in function templates |
25 | delegation.cpp | [class.base.init] | delegating constructor |
26 | enumeration.cpp | [dcl.enum] | type-safe enumerations |
27 | file.cpp | [iostreams.base] | file stream |
28 | foreach.cpp | [stmt.ranged] | range-based for |
29 | forwardlist.cpp | [forwardlist] | single linked list |
30 | future.cpp | [futures] | asynchronous results |
31 | hashtable.cpp | [unord.general] | hashtable |
32 | initializer.cpp | [support.initlist] | initializer lists |
33 | lambda.cpp | [expr.prim.lambda] | simple function objects |
34 | literals.cpp | [lex.ext] | user defined literals |
35 | math.cpp | [c.math] | math functions |
36 | move.cpp | [class.copy] | move semantic |
37 | mutex.cpp | [thread.mutex] | synchronization |
38 | nullptr.cpp | [lex.nullptr] | null |
39 | overridefinal.cpp | [class.virtual] | identifier |
40 | random.cpp | [rand] | random number generation |
41 | referencewrapper.cpp | [ref_wrap] | reference wrapper |
42 | regex.cpp | [re] | regular expressions |
43 | rightbrackets.cpp | [diff.cpp03.temp] | removed template whitespace |
44 | rvalues.cpp | [basic.lval] | lvalues, rvalues |
45 | smartpointer.cpp | [smartptr] | smart memory management |
46 | staticassert.cpp | [dcl.dcl] | compile time assertions |
47 | stringliterals.cpp | [lex.string] | string literals |
48 | thread.cpp | [thread.threads] | threading |
49 | tokens.cpp | [lex.digraph] | alternative tokens |
50 | trailingreturntype.cpp | [dcl.decl] | trailing return type |
51 | trigraph.cpp | [lex.trigraph] | alternative sequences |
52 | tuple.cpp | [tuple] | tuples |
53 | valarray.cpp | [numarray] | numeric arrays |
54 | variadictemplates.cpp | [temp.variadic] | variadic templates |
55 |
56 |
57 |
58 | Compile all snippets
59 | --------------------
60 |
61 | * cd src
62 | * make -j 4
63 |
64 |
65 | Compiler compatibility
66 | ----------------------
67 |
68 | Please see the documentation on what's currently supported by your compiler
69 |
70 | * [clang](http://clang.llvm.org/cxx_status.html) (preferably in combination with [libc++](http://libcxx.llvm.org/))
71 | * [g++](http://gcc.gnu.org/projects/cxx0x.html)
72 |
73 | e.g. the initializer list code compiles only with g++ >= 4.4 or clang++ >= 3.1, which in the latter case is a rather current version
74 |
--------------------------------------------------------------------------------
/TODO.md:
--------------------------------------------------------------------------------
1 | TODO
2 | ====
3 |
4 | There are no examples for the following features, yet
5 |
6 |
7 | List of missing examples
8 | -----------------------
9 |
10 | * perfect forwarding
11 | * functoid
12 | * atomic
13 | * inheriting constructors
14 | * ratio
15 | * alignment
16 | * type traits
17 | * mutable
18 | * hash
19 |
--------------------------------------------------------------------------------
/src/Makefile:
--------------------------------------------------------------------------------
1 | CXX ?= clang++
2 | CXXFLAGS ?= -std=c++11 -stdlib=libc++ -Wall -Wextra -Wno-trigraphs -Wno-unused-variable -g
3 | LDFLAGS ?= -lpthread
4 |
5 |
6 | all: $(patsubst %.cpp, %.out, $(wildcard *.cpp))
7 |
8 | %.out: %.cpp Makefile
9 | $(CXX) $(CXXFLAGS) $(LDFLAGS) $< -o $@
10 |
11 | clean:
12 | rm -f *.out
13 |
--------------------------------------------------------------------------------
/src/algorithms.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | using namespace std;
6 |
7 | int main() {
8 | vector v({1, 3, 4, 7});
9 |
10 | if(any_of(v.cbegin(), v.cend(), [](int i){ return i % 2 == 1; }))
11 | cout << "at least one int in v is odd" << endl;
12 |
13 | cout << "vector v sorted " << is_sorted(v.cbegin(), v.cend()) << endl;
14 |
15 | /* see also all_of, none_of, copy_if, find_if */
16 | }
17 |
--------------------------------------------------------------------------------
/src/aliastemplates.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | using namespace std;
5 |
6 |
7 | /*
8 | * Composition is now a tuple with an int as the fixed first type
9 | * see also the default function templates example
10 | */
11 |
12 | template
13 | using Composition = tuple;
14 |
15 |
16 | int main() {
17 | Composition composition(1, 2.3f, "name");
18 |
19 | cout << get<0>(composition) << endl;
20 | cout << get<1>(composition) << endl;
21 | cout << get<2>(composition) << endl;
22 | }
23 |
--------------------------------------------------------------------------------
/src/array.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | using namespace std;
5 |
6 | int main() {
7 | array a({{1, 2, 3}});
8 |
9 | cout << "first " << a.front() << endl;
10 | cout << "last " << a.back() << endl;
11 |
12 | for(auto x : a)
13 | cout << x << endl;
14 | }
15 |
--------------------------------------------------------------------------------
/src/auto.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | using namespace std;
5 |
6 | int main() {
7 | auto i = 3;
8 | decltype(i) a; /* a has now the type of i */
9 | auto l = {1, 2, 3}; /* l has now the type initializer_list */
10 |
11 | auto v = vector({4, 5, 6});
12 |
13 | for(auto x : v)
14 | cout << x << endl;
15 | }
16 |
--------------------------------------------------------------------------------
/src/chrono.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * workaround: needs to be defined in order to get the sleep method to work
3 | * see: /usr/include/c++/4.4.5/thread
4 | */
5 | #define _GLIBCXX_USE_NANOSLEEP
6 |
7 | #include
8 | #include
9 | #include
10 |
11 | using namespace std;
12 |
13 | int main() {
14 | /*
15 | * nanoseconds
16 | * microseconds
17 | * milliseconds
18 | * seconds
19 | * minutes
20 | * hours
21 | */
22 |
23 | const chrono::seconds sec(chrono::hours(1) + chrono::minutes(9) + chrono::seconds(8));
24 | cout << "1h 9m 8s = " << sec.count() << "s" << endl;
25 |
26 | /* get the duration of a section */
27 | const auto start(chrono::steady_clock::now());
28 | this_thread::sleep_for(chrono::seconds(3));
29 | const auto end(chrono::steady_clock::now());
30 |
31 | chrono::nanoseconds duration(end - start);
32 |
33 | cout << "duration of section: " << duration.count() << "ns"<< endl;
34 | cout << "duration of section: " << chrono::duration_cast(duration).count() << "ms"<< endl;
35 | }
36 |
--------------------------------------------------------------------------------
/src/constexpr.cpp:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | using namespace std;
4 |
5 | constexpr int square(int);
6 |
7 | int main() {
8 | constexpr double gr = 9.81;
9 |
10 | cout << static_cast(square(5)) * gr << endl;
11 | }
12 |
13 | constexpr int square(int x) {
14 | return x * x;
15 | }
16 |
17 | /* constexpr can be used at compile time and at run time, i.e. in templates or e.g. as array size */
18 |
--------------------------------------------------------------------------------
/src/defaultdelete.cpp:
--------------------------------------------------------------------------------
1 | class A {
2 | public:
3 | A() = default; /* explicit default constructor */
4 | A& operator=(const A&) = delete;
5 | A(const A&) = delete;
6 |
7 | void func(double);
8 | void func(int) = delete;
9 | };
10 |
11 | int main() {
12 | A t;
13 |
14 | /* compile time error t.func(3); */
15 | }
16 |
--------------------------------------------------------------------------------
/src/defaultfunctiontemplates.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | using namespace std;
5 |
6 |
7 | /*
8 | * Default first type of the tuple is int; opt. specify other type
9 | * see also the alias templates example
10 | */
11 |
12 | template
13 | tuple makeComposition(Key key, Types ... types) {
14 | return make_tuple(key, types ...);
15 | }
16 |
17 |
18 | int main() {
19 | auto composition = makeComposition(1, 2.3f, "name");
20 |
21 | cout << get<0>(composition) << endl;
22 | cout << get<1>(composition) << endl;
23 | cout << get<2>(composition) << endl;
24 | }
25 |
--------------------------------------------------------------------------------
/src/delegation.cpp:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | using namespace std;
4 |
5 | class myClass {
6 | public:
7 | explicit myClass(int i) { cout << "constructed with " << i << endl; }
8 | explicit myClass() : myClass(0) {}
9 | };
10 |
11 | int main() {
12 | myClass m; /* constructed with 0 */
13 | }
14 |
--------------------------------------------------------------------------------
/src/enumeration.cpp:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | using namespace std;
4 |
5 | /* type-safe enumeration, underlying type can be overridden */
6 | enum class Direction : unsigned int {
7 | North,
8 | East,
9 | South,
10 | West
11 | };
12 |
13 | int main() {
14 | Direction driving = Direction::North;
15 |
16 | if(driving == Direction::North)
17 | cout << "dragons ahead" << endl;
18 | }
19 |
--------------------------------------------------------------------------------
/src/file.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 |
6 | using namespace std;
7 |
8 | void funiq(const string &file) {
9 | fstream myFile;
10 | string linebuf;
11 | unordered_set uniq;
12 |
13 | try {
14 | /* only set flags for opening, otherwise we always get a eof exception */
15 | myFile.exceptions(ios_base::failbit | ios_base::badbit);
16 | myFile.open(file, ios_base::in);
17 | myFile.exceptions(ios_base::goodbit);
18 |
19 | /* insert each line to hashset */
20 | while(getline(myFile, linebuf))
21 | uniq.insert(linebuf);
22 |
23 | } catch(const ios_base::failure &e) {
24 | cout << "error reading file: " << e.what() << endl;
25 | }
26 |
27 | /* not sorted, b/c of unordered_set */
28 | for(auto x : uniq)
29 | cout << x << endl;
30 | }
31 |
32 | int main() {
33 | /* print unique lines */
34 | funiq("file.cpp");
35 | }
36 |
37 | /* see input stream handling for a 'uniq' program, to pipe content into */
38 |
--------------------------------------------------------------------------------
/src/foreach.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | using namespace std;
5 |
6 | int main() {
7 | vector v({1, 2, 3});
8 |
9 | for(auto x : v)
10 | cout << x << endl;
11 |
12 | /* see also for_each(v.begin(), v.end(), func) */
13 | }
14 |
--------------------------------------------------------------------------------
/src/forwardlist.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | using namespace std;
5 |
6 | /*
7 | * stores the program's parameters in a single linked list,
8 | * removes consecutive duplicates and sorts them by length
9 | *
10 | * call like this: ./a.out xx y y zz zz
11 | */
12 |
13 | int main(int argc, char** argv) {
14 | forward_list arguments(argv, argv+argc);
15 |
16 | cout << "file name: " << arguments.front() << endl;
17 |
18 | arguments.pop_front();
19 |
20 | // note: removes consecutive (!) duplicates
21 | arguments.unique();
22 |
23 | arguments.sort([](const string& a, const string& b){ return a.length() < b.length(); });
24 |
25 | for(const auto arg : arguments)
26 | cout << arg << endl;
27 | }
28 |
--------------------------------------------------------------------------------
/src/future.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | using namespace std;
5 |
6 | /* compile with -lpthread */
7 |
8 | int cfunc() {
9 | return 42; /* do your async calc here */
10 | }
11 |
12 | int main() {
13 | /* launch::async = asynchronous eval., launch::deferred = lazy eval. */
14 | future result = async(launch::async, cfunc);
15 |
16 | /* do other stuff, while the future result is calculated */
17 |
18 | cout << "we need the result now, and it is: " << result.get() << endl;
19 | }
20 |
--------------------------------------------------------------------------------
/src/hashtable.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | using namespace std;
5 |
6 | int main() {
7 | unordered_set uniq({4, 1, 4, 5, 4, 3, 2});
8 |
9 | cout << "size " << uniq.size() << endl;
10 |
11 | for(auto x : uniq)
12 | cout << x << endl;
13 |
14 | /* see also unordered_multiset, unordered_map, unordered_multimap */
15 | }
16 |
--------------------------------------------------------------------------------
/src/initializer.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | using namespace std;
6 |
7 | void flist(initializer_list);
8 |
9 | int main() {
10 | /* we use a scoped ptr for ease of use; initialize vector with values */
11 | const unique_ptr> v(new vector{1, 2, 3});
12 |
13 | for(auto x : *v)
14 | cout << x << endl;
15 |
16 | flist({4, 5, 6});
17 | }
18 |
19 | void flist(initializer_list list) {
20 | for(auto x : list)
21 | cout << x << endl;
22 | }
23 |
--------------------------------------------------------------------------------
/src/lambda.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | using namespace std;
6 |
7 | int main() {
8 | vector v({6, 1, 8, 2, 7, 6});
9 |
10 | for(auto x : v)
11 | cout << x << endl;
12 |
13 | /* sort by lambda, or functoid */
14 | sort(v.begin(), v.end(), [](int a, int b){ return a > b; });
15 |
16 | cout << "reverse sorted:" << endl;
17 |
18 | for(auto x : v)
19 | cout << x << endl;
20 |
21 | /* alt. incl. and use e.g. greater() */
22 | }
23 |
--------------------------------------------------------------------------------
/src/literals.cpp:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | using namespace std;
4 |
5 | /*
6 | * ask yourself this: do you really need user defined literals?
7 | */
8 |
9 | class Inch {
10 | public:
11 | explicit Inch() : Inch(0) { }
12 | explicit Inch(double value_) : value(value_) { }
13 |
14 | double toCentimeter() const { return value * 2.54; }
15 |
16 | private:
17 | double value = 0;
18 | };
19 |
20 | Inch operator "" _inch(long double arg) {
21 | return Inch(arg);
22 | }
23 |
24 | int main() {
25 | cout << (1.0_inch).toCentimeter() << " centimeter" << endl;
26 | }
27 |
--------------------------------------------------------------------------------
/src/math.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | using namespace std;
5 |
6 | int main() {
7 | float x = 1.333;
8 | float y = 3.461;
9 | float z = 9.023;
10 |
11 | /* (x*y)+z, rounded as one ternary operation */
12 | cout << "fma " << fma(x, y, z) << endl;
13 |
14 | /* sqrt(x^2 + y^2) */
15 | cout << "hypot " << hypot(x, y) << endl;
16 |
17 | /* NaN handling */
18 | cout << "NaN " << isnan(z) << endl;
19 |
20 | /* many cool new math functions, just look them up */
21 | }
22 |
--------------------------------------------------------------------------------
/src/move.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | using namespace std;
5 |
6 |
7 | class Fruit {
8 | public:
9 | Fruit(string& label_) : label(label_) { }
10 | Fruit(string&& label_) : label(move(label_)) { }
11 |
12 | /* copy constructor*/
13 | Fruit(const Fruit& other) : label(other.label) {
14 | cout << "copy constructor" << endl;
15 | }
16 |
17 | /* copy assign */
18 | Fruit& operator=(Fruit& other) {
19 | cout << "copy assign" << endl;
20 |
21 | label = other.label;
22 | return *this;
23 | }
24 |
25 | /* move constructor */
26 | Fruit(Fruit&& other) : label(move(other.label)) {
27 | cout << "move constructor" << endl;
28 | }
29 |
30 | /* move assign */
31 | Fruit& operator=(Fruit&& other) {
32 | cout << "move assign" << endl;
33 |
34 | label = move(other.label);
35 | return *this;
36 | }
37 |
38 | string getLabel() { return label; }
39 |
40 | private:
41 | string label;
42 | };
43 |
44 |
45 | int main() {
46 | Fruit firstFruit("extra juicy");
47 |
48 | /* copy */
49 | Fruit secondFruit(firstFruit);
50 | /* move */
51 | Fruit thirdFruit(move(firstFruit));
52 |
53 | /* copy */
54 | secondFruit = thirdFruit;
55 | /* move */
56 | firstFruit = move(thirdFruit);
57 | }
58 |
--------------------------------------------------------------------------------
/src/mutex.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | using namespace std;
6 |
7 | /* compile with -lpthread */
8 |
9 | /*
10 | * Prefer std::lock_guard over mutex.lock() and mutex.unlock(),
11 | * because the guard is exception-safe by using the RAII paradigm
12 | *
13 | * see also unique_lock, timed_mutex, recursive_mutex, recursive_timed_mutex
14 | */
15 |
16 | void runUnsynchronized() {
17 | long sharedCounter = 0;
18 |
19 | /* simply increment in each thread the shared counter */
20 | auto increment = [&sharedCounter](){
21 | for(int i = 0; i < 1000; ++i)
22 | ++sharedCounter;
23 | };
24 |
25 | thread firstThread(increment);
26 | thread secondThread(increment);
27 |
28 | firstThread.join();
29 | secondThread.join();
30 |
31 | cout << "unsynchronized shared counter: " << sharedCounter << " (expected to be 2000)" << endl;
32 | }
33 |
34 | void runSynchronized() {
35 | long sharedCounter = 0;
36 | mutex sharedMutex;
37 |
38 | /* locks the mutex and increments; guard is destroyed by leaving scope */
39 | auto increment = [&sharedCounter, &sharedMutex](){
40 | lock_guard scopedMutex(sharedMutex);
41 |
42 | for(int i = 0; i < 1000; ++i)
43 | ++sharedCounter;
44 | };
45 |
46 | thread firstThread(increment);
47 | thread secondThread(increment);
48 |
49 | firstThread.join();
50 | secondThread.join();
51 |
52 | cout << "synchronized shared counter: " << sharedCounter << " (expected to be 2000)" << endl;
53 | }
54 |
55 | int main() {
56 | runUnsynchronized();
57 | runSynchronized();
58 | }
59 |
--------------------------------------------------------------------------------
/src/nullptr.cpp:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | using namespace std;
4 |
5 | int main() {
6 | int *p = nullptr; /* normally you get a pointer e.g. from a function */
7 |
8 | if(p == nullptr)
9 | cout << "null" << endl;
10 | else
11 | cout << "not null" << endl;
12 |
13 | /* the type-safe nullptr is of type std::nullptr_t and of size sizeof(void*) */
14 | }
15 |
--------------------------------------------------------------------------------
/src/overridefinal.cpp:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | using namespace std;
4 |
5 | /* use final on a class to prevent inheriting; compilation error */
6 | class A /* final */ {
7 | public: virtual void func(int) { cout << "A::func()" << endl; }
8 | };
9 |
10 | class B : A {
11 | /* use override to make the compiler checks that we are indeed overriding an inherited method */
12 | public: virtual void func(int) override { cout << "B::func()" << endl; }
13 |
14 | /* virtual void func(char) override {} compilation error; new method (see signature), does not override existing */
15 | };
16 |
17 | int main() {
18 | A t;
19 | t.func(2);
20 |
21 | B u;
22 | u.func(3);
23 | }
24 |
--------------------------------------------------------------------------------
/src/random.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include