C++17: Lambdas

C++ has supported lambda functions since C++11, and post-C++14 even supported generic lambdas. C++17 adds a quirky feature to enable ‘copy capture’ of ‘this’. Here’s an example of it in action:

struct MyStruct
    auto lambda_with_this() // Before C++17, copies this pointer
        auto f = [this]{ return value; };
        return f;
    auto lambda_with_star_this() // C++17 - takes a local copy of *this
        auto f = [*this]{ return value; };
        return f;
    int value;

TEST( Cpp17, lambda_capture_this )
    MyStruct s{ 42 };
    auto f = s.lambda_with_this();
    s.value = 101;
    EXPECT_EQ( 101, f() );

TEST( Cpp17, lambda_capture_star_this )
    MyStruct s{ 42 };
    auto f = s.lambda_with_star_this();
    s.value = 101;
    EXPECT_EQ( 42, f() );

Notice that in the second case, we capture a copy of our object – so the lambda returns the value held at the point of capture (42) rather than the value when it is called (101). This can be very important if ‘this’ has been destroyed between the creation of the lambda and the time at which it’s called.

Now, C++14 also supported generalised lambda capture, which meant you could (re-)name variables when capturing (and provided a neat way to capture-by-move):

    auto f = [tmp = *this]{ return tmp.value; };

But the C++17 code is more concise. See this useful StackOverflow post for more discussion.

Another advance in C++17 is that lambdas are implicitly constexpr – so you can now use them in compile-time contexts, like declaration of std::array:

// lambda explicitly constexpr since C++17
auto square = []( auto v ){ return v*v; }; 

TEST( Cpp17, lambda_implicitly_constexpr )
    // std::array calls 'square()' at compile time
    std::array<int, square(4)> values; 
    EXPECT_EQ( 16, values.size() );

See also the previous C++17 post.

Leave a comment

Filed under C++, C++ Code, Programming

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s