In this post, I’m going to highlight some of the new language features in the draft of the C++14 standard. This is an excerpt from my book C++11 Rocks: VS2013 Edition. I looked at the level of C++14 support in different compilers in a previous post.

Return type deduction for functions

The compiler will be able to deduce the return type of functions:

auto square(int n) 
{
    return n * n;
}

To get the compiler to figure out the return type, you start the declaration with auto but don’t specify a trailing return type. This is basically extending the return type deduction VS2013 does for lambdas to regular functions.

Generic lambdas

When specifying lambda parameters, you’ll be able to use auto instead of a type:

auto lambda = [](auto a, auto b) { return a * b; };

In C++ pseudocode, this definition is equivalent to the following:

struct lambda1
{
    template<typename A, typename B>
    auto operator()(A a, B b) const -> decltype(a * b)
    {
        return a * b;
    }
};

auto lambda = lambda1();

So using auto for parameters effectively makes the function call operator templated. The types of the parameters will be determined using the rules for template argument deduction rather than the type inference that happens with regular auto variables.

Extended capturing in lambdas

Another change to lambdas involves capturing variables. In C++14, captured variables can have an initializing expression:

auto timer = [val = system_clock::now()] { return system_clock::now() - val; };
// ... do stuff ...
timer();   // returns time since timer creation

In this example, val is assigned the current time which is then returned by the lambda expression. val doesn’t need to be an existing variable, so this is in effect a mechanism for adding data members to the lambda. The types of these members are inferred by the compiler.

This allows capturing move-only variables which isn’t possible in C++11:

auto p = make_unique<int>(10);
auto lmb = [p = move(p)] { return *p; }

It is equivalent to capturing a variable via move, although what’s happening under the hood is a bit more tricky. In reality, the capture block declares a new data member in the lambda called p. This member is initialized with p from outside the lambda which is cast to an rvalue reference.

Revised restrictions on constexpr functions

The proposal lists the following things which are going to be allowed in constexpr functions:

  • declarations in constexpr functions with the exception of static, thread_local or uninitialized variables
  • if and switch statements
  • looping constructs, including range-based for
  • modification of objects whose lifetime began within the constant expression evaluation.

This should make constexpr functions a lot more versatile.

constexpr variable templates

In addition to type and function templates, C++14 will allow constexpr variables to be templated. Here is how it will work:

template<typename T>
constexpr T pi = T(3.1415926535897932385);

There is no new syntax, the already existing template syntax is simply applied to a variable here. This variable can then be used in generic functions:

template<typename T>
T area_of_circle_with_radius(T r) 
{
    return pi<T> * r * r;
}

The idea is that despite having a single initializing expression, it’s sometimes useful to vary the type of a variable used in a generic function.

More changes

There are more language changes on the way. They include: [list style=”arrow” color=”blue”]

  • Another alternative for type inference which will allow you to use decltype inference rules for auto variables.
  • Aggregate initialization will work for classes with in-class member initializers.
  • Built-in binary literals prefixed with 0b.
  • It’ll be possible to separate digits in a numeric literal with a single quote.
  • Another standard attribute called [[deprecated]] will be added with the purpose of marking deprecated parts of the code. [/list]

The standard is expected to be finalized some time this year. The good thing is that the work on adding new features into compilers is already well under way, and some of the features I described in this post can already be used.