This post is a summary of new features in C++14. Briefly C++14 feels like it is not a major version however it is more like an add-on for C++11. It improves features introduced in C++11.
Regarding compiler support for C++14 , you can see the table from en.cppreference.com :
- Constexpr with less constraints : C++11 introduced constexpr however you can not use branches ( if elses ) and looping. In C++11 you had the workaround of using ternary expressions and recursions :
In C++14 , you can now use branches and loops and you can also have more than one return statements :
Note that you still have limitations such as :
- You can not use goto , inline assembly , thread local and static variables
- You can only assign literals to variables
The assembly output of above C++14 constexpr call can be seen as below :
2. Auto as return type , decltype(auto) and template functions
In C++03 , you could not generalise the return type of a template function if it was depending on template arguments :
In C++11 , using decltype was not helping as the compiler was parsing from left to right. Therefore you could not compile the below example :
As a solution for C++11 , you can use auto as returning type of a function in C++11, however you also had to use trailing return types ( part starting with -> ) as the parsing is from left to right :
In C++14, you will not need trailing return types anymore :
On the other hand , C++14 auto return type can not deduce constness or references. As a solution, you can use decltype(auto) as return value in order to keep constness or being a reference :
3. Lambda capture initialisers : You can evaluate arbitrary expressions in lambda captures , assign them to variables that is only in scope of your lambda expression :
4. Generic lambdas : You can now use auto for function arguments which allows you to write even more powerful lambda expressions :
5. Variable templates :
Before C++14, when you wanted to use template classes as simple value evaluators , you had to use templateClasss<input>::value idiom. On the other hand you do not to use that syntax anymore as now you can use variable templates which is more practical to code and more expressive. Below the first example is without use of variable templates and the 2nd one shows use variable templates :
Below you can see a nice use of this feature combined with std::accumulate :
6. Binary literals and digit seperators : You can define a numeric literal in hexadecimal using 0x notation. In C++14 , now you can use 0b notation for binary literals. Additionally ,you can use apostrophe to group bits byte-by-byte :
7. Heap ellision : This is a feature initially implemented by Clang compiler and eventually proposed and accepted for C++14. It basicalliy allows compiler to optimise out memory allocations. You can see the proposal here : http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3664.html
Currently Clang compilers later than version 3.0 applies this optimisation. You can see that Clang applies this whereas GCC does not , below :
Note that , this is a feature that can hide memory leaks as you move your project from one compile to another.
8. Library features :
a) std::make_unique : C++11 introduced std::make_shared however it lacked make_unique. In C++14 , now you can use make_unique from the standard library to construct your std::unique_ptr
b) std::shared_timed_mutex & std::shared_lock : It is a multiple reader and single writer mutex. It is quite useful for scenarios where there is frequent reads but rare updates.
std::shared_lock is similar to std::unique_lock and it supports exclusive locks. The difference is that it also supports std::shared_timed_mutex for shared-access pattern.
An example can be seen here :
c) Chrono literals : C++11 introduced user defined literals. C++14 provides prebuilt literals supporting Chrono date time libray which helps to produce more readible code ;