User:Gregory.currie/Test

Auto
Why you would: What cases wouldn't you use auto:
 * The type is unexpressable due to implementation defined types
 * Shorter, cuts the crap
 * Avoiding initialiser list being inferred
 * initialiser lists (auto z = {42} // not an array of 1 int

auto x = foo + somethingelse & /* ... */ some_heavily_overloaded_function(x); // What's called here? Is this the long overload, the long long, the CDonkey overload, what?
 * You want a different type for your identifer to what the expression returns
 * It won't be clear exactly what the type will be to fellow coders.
 * You may instead go:

long x = foo + somethingelse & /* ... */ some_heavily_overloaded_function(x); // Ah... It's the long overload
 * Downside to this is sometimes you shouldn't care.
 * i.e. You can't change the result of expression from long to long long without requiring x to be updated before the correct overload is called

Uniform Initialization and initializer_lists
Use {} unless there is one of the three reasons below:


 * It's a simple case that looks cleaner with initialization

int i = 42; auto iter = begin(vec);


 * You want to avoid an initializer_list being used.

vector vec {100}; // Create 100 ints in this vector vector vec {100} // Create a single element with the value 100


 * You're using auto and don't want to capture an initializer_list

int n = 42; auto m {n}; // oops - m is now an initializer_list int m = n; // Much better

range for, begin and end
Use everywhere. Cases where you can't:


 * Container without .begin/.end/iterator semantics
 * In this case, define you own global overload (free function) for begin and end that accepts a parameter of the container in question. You are extending the interface of the container without having to modify it. Define your own iterator class, and you're done.

Smart Pointers
Use one of the smart pointers where possible. Times you would not use a smart pointer:


 * You don't have ownership of the object in question, and know the object will outlast you. - Don't care about lifetime.

Don't use a "raw" construction, use make_shared. Why?


 * Saves memory
 * Faster
 * Usually less typing

Move semantics, &&
Example:

vecto&lt;int&gt; make_vec { // Return type is NOT vector &&, just a regular vector vecto&lt;int&gt; vector; // ...   return vector; // !!! Actually very fast } Why?
 * Easier to use, than caller create
 * Lifetime is managed (unlike pointers)
 * Just as fast (well, almost - even move has slight overhead).

Lambdas
Just as fast as regular function calls

Beware of gotchas:
 * Capture-by-reference closed variables have the same semantics as regular references, i.e. They can go out of scope

Emplace_back
vector vec; vec.emplace_back(42,"Hello"); vec.push_back(make_pair(42,"Hello"));

Why?
 * A little faster
 * Simplier expressions