├── .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 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 |
filereferencedescription
algorithms.cpp[algorithms]algorithm on container, using lambda
aliastemplates.cpp[temp.alias]alias templates
array.cpp[array]constant size array container
auto.cpp[dcl.spec.auto]auto type-specifier for variables
chrono.cpp[time.syn]time utilities
constexpr.cpp[expr.const]compile time and run time const
defaultdelete.cpp[dcl.fct.def.general]defaulted and deleted definition
defaultfunctiontemplates.cpp[temp.param]default arguments in function templates
delegation.cpp[class.base.init]delegating constructor
enumeration.cpp[dcl.enum]type-safe enumerations
file.cpp[iostreams.base]file stream
foreach.cpp[stmt.ranged]range-based for
forwardlist.cpp[forwardlist]single linked list
future.cpp[futures]asynchronous results
hashtable.cpp[unord.general]hashtable
initializer.cpp[support.initlist]initializer lists
lambda.cpp[expr.prim.lambda]simple function objects
literals.cpp[lex.ext]user defined literals
math.cpp[c.math]math functions
move.cpp[class.copy]move semantic
mutex.cpp[thread.mutex]synchronization
nullptr.cpp[lex.nullptr]null
overridefinal.cpp[class.virtual]identifier
random.cpp[rand]random number generation
referencewrapper.cpp[ref_wrap]reference wrapper
regex.cpp[re]regular expressions
rightbrackets.cpp[diff.cpp03.temp]removed template whitespace
rvalues.cpp[basic.lval]lvalues, rvalues
smartpointer.cpp[smartptr]smart memory management
staticassert.cpp[dcl.dcl]compile time assertions
stringliterals.cpp[lex.string]string literals
thread.cpp[thread.threads]threading
tokens.cpp[lex.digraph]alternative tokens
trailingreturntype.cpp[dcl.decl]trailing return type
trigraph.cpp[lex.trigraph]alternative sequences
tuple.cpp[tuple]tuples
valarray.cpp[numarray]numeric arrays
variadictemplates.cpp[temp.variadic]variadic templates
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 4 | 5 | using namespace std; 6 | 7 | int main() { 8 | /* 9 | * engine: speed: storage requirement: quality: 10 | * 11 | * linear_congruential_engine + ++ + 12 | * mersenne_twister_engine + - ++ 13 | * subtract_with_carry_engine ++ + + 14 | */ 15 | 16 | random_device device; 17 | mt19937 generator(device()); 18 | uniform_int_distribution udistribution(2, 7); 19 | binomial_distribution bdistribution(5, 0.5); 20 | 21 | map histogram; 22 | 23 | cout << "mersenne twister, uniform distribution(2, 7):" << endl; 24 | 25 | for(int i = 0; i < 10000; ++i) 26 | ++histogram[udistribution(generator)]; 27 | for(auto x : histogram) 28 | cout << x.first << '\t' << string(x.second / 50, '*') << endl; 29 | histogram.clear(); 30 | 31 | cout << "mersenne twister, binomial distribution(5, 0.5):" << endl; 32 | 33 | for(int i = 0; i < 10000; ++i) 34 | ++histogram[bdistribution(generator)]; 35 | for(auto x : histogram) 36 | cout << x.first << '\t' << string(x.second / 50, '*') << endl; 37 | histogram.clear(); 38 | 39 | 40 | /* many different engines and distributions are defined, so look them up */ 41 | } 42 | -------------------------------------------------------------------------------- /src/referencewrapper.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | int main() { 8 | string firstWord{"camera"}; 9 | string secondWord{"moon"}; 10 | string thirdWord{"bed"}; 11 | 12 | vector valVec{ 13 | firstWord, secondWord, thirdWord 14 | }; 15 | 16 | /* not allowed: vector, instead use a wrapper */ 17 | vector> refVec{ 18 | ref(firstWord), ref(secondWord), ref(thirdWord) 19 | }; 20 | 21 | /* now lets change an item */ 22 | secondWord = "sky"; 23 | 24 | cout << "val: "; 25 | for(string valItem : valVec) 26 | cout << valItem << " "; 27 | cout << endl; 28 | 29 | cout << "ref: "; 30 | for(string& refItem : refVec) 31 | cout << refItem << " "; 32 | cout << endl; 33 | } 34 | -------------------------------------------------------------------------------- /src/regex.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | int main() { 8 | const regex pattern("(0+1+0+)"); 9 | const string firstWord("00010"); 10 | const string secondWord("abc00010def011110ghi"); 11 | 12 | cout << "matched whole string: " << boolalpha << regex_match(firstWord, pattern) << endl; 13 | cout << "matched whole string: " << boolalpha << regex_match(secondWord, pattern) << endl; 14 | 15 | /* 16 | * is not fully implemented in the latest libstdc++, 17 | * e.g. regex_search, regex_replace, ... are not yet implemented 18 | * 19 | * see: http://gcc.gnu.org/onlinedocs/libstdc++/manual/status.html#status.iso.2011 20 | * 21 | * I compiled the following lines with clang 3.2 (trunk 157606) and -stdlib=libc++ 22 | */ 23 | 24 | cout << "matched sub string: " << boolalpha << regex_search(secondWord, pattern) << endl; 25 | 26 | cout << "replaced with X: " << regex_replace(secondWord, pattern, "X") << endl; 27 | } 28 | -------------------------------------------------------------------------------- /src/rightbrackets.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | int main() { 6 | vector> v; 7 | 8 | /* before c++11 blank between brackets needed: vector > v; */ 9 | } 10 | -------------------------------------------------------------------------------- /src/rvalues.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | 7 | /* takes an lvalue reference */ 8 | void getPackage(string& desc) { 9 | cout << desc << ", getPackage called with lvalue reference" << endl; 10 | } 11 | 12 | /* takes an rvalue reference */ 13 | void getPackage(string&& desc) { 14 | cout << desc << ", getPackage called with rvalue reference" << endl; 15 | } 16 | 17 | 18 | int main() { 19 | string desc("first description"); 20 | 21 | /* called with lvalue */ 22 | getPackage(desc); 23 | 24 | /* called with rvalue; temp object */ 25 | getPackage(string("second description"));; 26 | 27 | /* see also the move semantic example */ 28 | } 29 | -------------------------------------------------------------------------------- /src/smartpointer.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | int main() { 7 | unique_ptr uptr1(new int(5)); /* only uptr1 manages the memory, only able to move or swap the ownership */ 8 | unique_ptr uptr2(move(uptr1)); /* now uptr2 manages the memory, uptr1 is invalid */ 9 | 10 | cout << "unique_ptr\tuptr2 points to memory address " << uptr2.get() << ", with content " << *uptr2.get() << endl; 11 | 12 | uptr1.reset(); /* does nothing */ 13 | uptr2.reset(); /* deletes the memory */ 14 | 15 | if(!uptr1 && !uptr2) 16 | cout << "unique_ptr\tboth do not own an object, memory was successfully deleted" << endl; 17 | 18 | 19 | shared_ptr sptr1(new int(10)); 20 | shared_ptr sptr2(sptr1); 21 | 22 | /* 23 | * note on performance: statements above perform two memory allocations; only one with 24 | * auto sptr = make_shared(10); 25 | */ 26 | 27 | cout << "shared_ptr\tref count is " << sptr2.use_count() << endl; 28 | sptr1.reset(); 29 | cout << "shared_ptr\tref count is " << sptr2.use_count() << endl; 30 | sptr2.reset(); 31 | 32 | if(!sptr1 && !sptr2) 33 | cout << "shared_ptr\tboth do not own an object, memory was successfully deleted" << endl; 34 | 35 | /* see also weak_ptr; use const unique_ptr instead of boost's scoped_ptr */ 36 | } 37 | -------------------------------------------------------------------------------- /src/staticassert.cpp: -------------------------------------------------------------------------------- 1 | int main() { 2 | static_assert(sizeof(char) == 1, "char assert went wrong"); 3 | static_assert(sizeof(int) == 4, "int assert went wrong"); 4 | static_assert(sizeof(double) == 8, "double assert went wrong"); 5 | 6 | /* compile time assertions */ 7 | } 8 | -------------------------------------------------------------------------------- /src/stringliterals.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | int main() { 6 | const char a[] = u8"utf-8 \u2018"; 7 | auto regex(R"(a\bc"d)"); 8 | 9 | cout << regex << endl; 10 | cout << a << endl; 11 | } 12 | -------------------------------------------------------------------------------- /src/thread.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | /* compile with -lpthread */ 7 | 8 | class Runnable { 9 | private: 10 | int value; 11 | public: 12 | explicit Runnable(int _value) : value(_value) {} 13 | void operator()() const { cout << "thread, value is " << value << endl; } 14 | }; 15 | 16 | int main() { 17 | /* opt. use myThread(func, arg0, arg1, ...) for threaded functions */ 18 | Runnable myRunnable(3); 19 | thread myThread(myRunnable); 20 | 21 | myThread.join(); 22 | 23 | /* 24 | * use lock_guard to synchronize a scope 25 | * or manage the critical section manually by using mutex 26 | * 27 | * avoid deadlocks by locking more than one mutex with lock(m0, m1, ...) 28 | * transfer, unlock after scope: lock_guard guard(m0, adopt_lock); 29 | */ 30 | } 31 | -------------------------------------------------------------------------------- /src/tokens.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | /* 6 | Alternative Primary 7 | <% { 8 | and && 9 | and_eq &= 10 | %> } 11 | bitor | 12 | or_eq |= 13 | <: [ 14 | or || 15 | xor_eq ˆ= 16 | :> ] 17 | xor ˆ 18 | not ! 19 | %: # 20 | compl ∼ 21 | not_eq != 22 | %:%: ## 23 | bitand & 24 | */ 25 | 26 | %: define OUT 27 | 28 | int main() { 29 | int a<::> = <% 2,3 %>; 30 | 31 | %: if defined(OUT) 32 | cout << a<:0:> << endl; /* output is 2 */ 33 | %: else 34 | cout << a<:1:> << endl; /* output is 3 */ 35 | %: endif 36 | } 37 | -------------------------------------------------------------------------------- /src/trailingreturntype.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | /* specifies the return type as type of the addition result */ 6 | template auto add(const T& t, const U& u) -> decltype(t + u) { 7 | return t + u; 8 | } 9 | 10 | /* trailing return types for alternative function syntax */ 11 | auto main() -> int { 12 | 13 | /* lambda with explicit return type */ 14 | auto func = [](const int& x, const int& y) -> int { return x + y; }; 15 | 16 | cout << func(2, 3) << endl; 17 | 18 | cout << add(3.8, 2) << endl; 19 | } 20 | -------------------------------------------------------------------------------- /src/trigraph.cpp: -------------------------------------------------------------------------------- 1 | ??=include 2 | 3 | using namespace std; 4 | 5 | /* 6 | Trigraph Replacement 7 | ??= # 8 | ??( [ 9 | ??< { 10 | ??/ \ 11 | ??) ] 12 | ??> } 13 | ??' ˆ 14 | ??! | 15 | ??- ∼ 16 | */ 17 | 18 | int main() { 19 | int a??(??) = ??< 2,3 ??>; 20 | 21 | cout << a??(0??) << endl; /* output is 2 */ 22 | } 23 | -------------------------------------------------------------------------------- /src/tuple.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | int main() { 7 | tuple firstRecord(42, "myFirstName", 1.303); 8 | tuple secondRecord(21, "mySecondName", 2.638); 9 | 10 | auto concat = tuple_cat(firstRecord, secondRecord); 11 | 12 | /* for printing a tuple of any size you have to recursively use templates */ 13 | cout << get<1>(concat) << " " << get<4>(concat) << endl; 14 | 15 | 16 | const int a = 1; 17 | const int b = 2; 18 | const double x = 2.34; 19 | const double y = 4.27; 20 | 21 | /* tie creates a tuple from lvalue references */ 22 | if(tie(a, x) < tie(b, y)) 23 | cout << "second arguments are larger" << endl; 24 | 25 | /* 26 | * use this to easily implement e.g. 27 | * bool operator<(const A& rhs) const { return tie(n, s, d) < tie(rhs.n, rhs.s, rhs.d); } 28 | */ 29 | 30 | 31 | int f = 1; 32 | int g = 2; 33 | int h = 3; 34 | 35 | /* unpack variables */ 36 | tie(f, g, h) = tie(g, f, h); 37 | 38 | cout << "f " << f << ", g " << g << ", h " << h << endl; 39 | /* 40 | * f=2, g=2, h=3, because it is evaluated as follows: 41 | * f = g; -> f=2 42 | * g = f; -> g=2 43 | * h = h; -> h=3 44 | */ 45 | } 46 | -------------------------------------------------------------------------------- /src/valarray.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | template 7 | void valprint(valarray v) { 8 | for(int i = 0; i < static_cast(v.size()); ++i) 9 | cout << v[i] << " "; 10 | cout << endl; 11 | } 12 | 13 | int main() { 14 | /* optimized value array */ 15 | valarray v({1, 2, 3, 4, 5, 6, 7, 8}); 16 | valarray w({4, 7, 9, 2, 7, 2, 4, 9}); 17 | 18 | cout << "v: "; 19 | valprint(v); 20 | 21 | cout << "sum " << v.sum() << endl; 22 | cout << "min " << v.min() << endl; 23 | cout << "max " << v.max() << endl; 24 | 25 | /* note: v is still the same, shift and cshift are returning new valarrays */ 26 | 27 | cout << "shift(2): "; 28 | valprint(v.shift(2)); 29 | 30 | cout << "cshift(2): "; 31 | valprint(v.cshift(2)); 32 | 33 | /* valarray.apply() is basically the same as for_each */ 34 | 35 | /* math on valarrays */ 36 | valarray result((v^(v*w))+v); 37 | cout << "(v^(v*w))+v: "; 38 | valprint(result); 39 | 40 | /* "Any function returning a valarray is permitted to return an object of another type" */ 41 | } 42 | -------------------------------------------------------------------------------- /src/variadictemplates.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | /* 6 | * If there's more than one item we split the first one (head) off 7 | * and continue with the rest (tail) recursively until we are done 8 | */ 9 | 10 | template 11 | void processItem(Head item) { 12 | cout << item << endl; 13 | } 14 | 15 | template 16 | void processItem(Head item, Tail ... tail) { 17 | processItem(item); 18 | processItem(tail ...); 19 | } 20 | 21 | int main() { 22 | processItem("Hello", "my friend", "how are you", "today?"); 23 | processItem("Look at all those fancy types", 1, 2.3f); 24 | } 25 | --------------------------------------------------------------------------------