C++17: Core language features (part 1)

A u8 character literal

In C++17 was added new character literal for UTF-8.

For example:

It’s used for correct translation characters to ASCII on different platforms.

 

Hexadecimal floating point literals

In C++17 was added hexadecimal floating point literals.

Link for cppreference.

template<auto>

Allows avoiding type name in templates. For example, in C++14 it was:

and in C++17 it looks like this:

Type of x will be deduced by a compiler.

Also, it’s possible to use auto with variadic templates:

 

class template argument deduction

In C++17 template parameters can be deduced by a compiler. For example in C++14:

and in C++17 it will be:

The same rule works with operator new:

 

constexpr if

constexpr if allows check conditions on compile time. For example:

or:

 

selection statements with initializer

In C++17 there are new versions of if and switch statements:

  • if ( init; condition)
  • switch(init; condition)

It was added because there is a lot of cases where a variable is created only to use inside some if or switch statement.

For example before C++17:

and on C++17:

Switch statement C++14:

switch C++17:

 

constexpr lambdas

In C++17 was added ability create lambda as constexpr.

For example:

 

lambda capture of *this

In C++17 now it’s possible to pass *this to lambda.

For example:

Lambda expressions declared within a non-static member function explicilty or implicitly captures the this pointer to access to member variables of this. Both capture-by-reference [&] and capture-by-value [=] capture-defaults implicitly capture the this pointer, therefore member variables are always accessed by reference via this. Thus the capture-default has no effect on the capture of this. Asynchronous dispatch of closures is a cornerstone of parallelism and concurrency. When a lambda is asynchronously dispatched from within a non-static member function, via std::async or other concurrency / parallelism dispatch mechanism, the *this object cannot be captured by value. Thus when the std::future (or other handle) to the dispatched lambda outlives the originating class the lambda’s captured this pointer is invalid.

There is a workaround on C++14:

This workaround has two liabilities. First, this pointer is also captured which provides a significant opportunity to erroneously reference a this->member instead of a tmp.member as there are two distinct objects in the closure that reference two distinct members of the same name. Second, it is onerous and counter-productive to the introduction of asynchronously dispatched lambda expressions within existing code. Consider the case of replacing a for loop within a non-static member function with a parallel for each construct as in the parallelism technical specification.

Leave a Reply

Your email address will not be published.