Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

generalized lambda capture in uniform initialization failed to compile

Tags:

c++

c++14

why this code failed to compile? I am using clang 3.4 with -std=c++1y

struct Foo {
    template <class T>
    Foo(T) {}
};

void bar()
{
    std::vector<int> vec;
    auto func = [vec{std::move(vec)}] () { };
    Foo f1 { func};  // compile
    Foo f2 { [vec] () { } }; // compile
    Foo f3 { [vec{std::move(vec)}] () {} }; // failed to compile
}

error message and flags

like image 702
Bryan Chen Avatar asked Mar 31 '26 18:03

Bryan Chen


1 Answers

This was a Clang bug, caused by an interaction between C++14 lambda init-captures and C99 designated initializers.

C99's designated initializers include this syntax:

int arr[] = { [2] = 42 };

Clang supports them as an extension in C++ as well as in C, and thus when it sees a [ within { ... }, it needs to figure out whether that's the start of a lambda-expression or an array designator (or an attribute-specifier, or in Objective C++11, a message send expression).

Unfortunately, this disambiguation logic was not updated when Clang gained support for C++1y init-captures, so Clang believed that

Foo f3 { [vec{

... must be an array designator (because { cannot appear within a C++11 lambda's capture list).

I fixed this in Clang SVN r206128, and the fix will be in Clang 3.5. In the mean time, you can work around this with parentheses:

Foo f3 { ([vec{std::move(vec)}] () {}) };
like image 120
Richard Smith Avatar answered Apr 03 '26 07:04

Richard Smith