Klaus Klaus - 2 months ago 13
C++ Question

lambda inside subscript iterator

Having a lambda in a subscript operator seems to be not working for g++ and clang.

Is this an implementation error or a "unhappy" rule in c++ standard?

Example:

class A
{
public:
template<typename T> void operator[](T) {}
template<typename T> void operator()(T) {}
};

int main()
{
A a;
a[ [](){} ]; // did not compiler: see error message
a( [](){} ); // works as expected
}


Error:

main.cpp:13:6: error: two consecutive '[' shall only introduce an attribute before '[' token
a[ [](){} ];
^
main.cpp:13:15: error: expected primary-expression before ']' token
a[ [](){} ];


I know that attributes starts with "[[" but I am wondering that "[ [" ( with one or more white spaces ) also works like:

void func( int x [ [gnu::unused] ] ) {} // compiles fine! :-(

Answer

This is covered in [dcl.attr.grammar]. Having two consecutive [ is an attribute, so you'll have to wrap in parantheses or do something else to make your intent clear:

Two consecutive left square bracket tokens shall appear only when introducing an attribute-specifier or within the balanced-token-seq of an attribute-argument-clause. [ Note: If two consecutive left square brackets appear where an attribute-specifier is not allowed, the program is ill-formed even if the brackets match an alternative grammar production. —end note ] [ Example:

int p[10];
void f() {
  int x = 42, y[5];
  int(p[[x] { return x; }()]);   // error: invalid attribute on a nested
                                 // declarator-id and not a function-style cast of
                                 // an element of p.
  y[[] { return 2; }()] = 2;     // error even though attributes are not allowed
                                 // in this context.
  int i [[vendor::attr([[]])]];  // well-formed implementation-defined attribute.
}

—end example ]

Comments