jeudi 1 octobre 2015

Lambda capture reference by copy and decltype

Consider the simple program:

int i = 0;
int& j = i;

auto lambda = [=]{
    std::cout << &j << std::endl; //odr-use j
};

According to [expr.prim.lambda], the closure member variable j should have type int:

An entity is captured by copy if it is implicitly captured and the capture-default is = or if it is explicitly captured with a capture that is not of the form & identifier or & identifier initializer. For each entity captured by copy, an unnamed non-static data member is declared in the closure type. The declaration order of these members is unspecified. The type of such a data member is the type of the corresponding captured entity if the entity is not a reference to an object, or the referenced type otherwise.

So what I'm printing is the address of some int unrelated to the outer-scope i or j. This is all well and good. However, when I throw in decltype:

auto lambda = [j] {
    std::cout << &j << std::endl;
    static_assert(std::is_same<decltype(j), int>::value, "!"); // error: !
};

That fails to compile because decltype(j) evaluates as int&. Why? j in that scope should refer to the data member, should it not?

Aucun commentaire:

Enregistrer un commentaire