Используя Visual C ++ 2013, следующий код выдает странную ошибку компиляции:
/// header.h
class Test
{
public:
template <typename Func>
void operator[](Func f)
{
f();
}
};
template <typename T>
void funct()
{
Test t;
t[[](){; }]; // line 16 // The same error with t[ ([](){; }) ];
}
/// main.cpp
int main()
{
funct<int>();
// funct();
}
Ошибки:
1>c:\path\to\header.h(16): error C2958: the left bracket '[' found at 'e:\path\to\header.h(16)' was not matched correctly
1>c:\path\to\header.h(16): error C2059: syntax error : ']'
1>c:\path\to\header.h(17): error C2059: syntax error : '}'
1>c:\path\to\header.h(17): error C2143: syntax error : missing ';' before '}'
Эта ошибка не возникает, когда тело лямбда-функции не имеет никаких операторов:
template <typename T>
void funct()
{
Test t;
t[[](){ }]; // line 16 // No semicolon - No statement - No errors
}
Или когда функция не является шаблоном:
// Ordinary function - No errors
void funct()
{
Test t;
t[[](){; }]; // line 16
}
Я думаю, что нашел ошибку в этом компиляторе. Однако, если кто-нибудь знает способ написать это без ошибок и без использования переменной для хранения лямбда-функции, это было бы здорово.
VC ++ правильно отклоняет этот код, но по неправильным причинам — это ошибка. Это плохо сформировано согласно [dcl.attr.grammar] / 6:
Два последовательных жетона левой квадратной скобки должны появляться только тогда, когда
представляя Атрибут спецификатор. [ Замечания:
Если появляются две последовательные левые квадратные скобки, где указатель атрибута не разрешен, программа
неправильно сформирован, даже если скобки соответствуют альтернативному грамматическому произведению. — конец примечания ] [ Пример: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. }
— конец примера ]
Поэтому попробуйте заключить лямбда-выражение в два паратеза следующим образом.
t[ ([](){; }) ];
Или пиши
auto&& closure = [](){; };
t[closure]; // move here if correct value category is desired