2016-09-09 3 views
9

첨자 연산자에서 람다를 사용하면 g ++ 및 clang에서 작동하지 않는 것으로 보입니다.아래 첨자 내 람다

이 구현 오류 또는 C++ 표준의 "불행한"규칙입니까?

예 :

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 
} 

오류 : 나는 속성이 알고

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[ [](){} ]; 

는 "[["그러나 나는 또한 "[["(하나 이상의 공백을) 궁금 시작 다음과 같이 작동합니다 :

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

답변

4

이 [dcl.attr.grammar]에 덮여와 인수를 마무리 할 수 ​​있습니다. 다른 상황에서 이러한 호기심 예를 볼 위대한

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 ]

+1

추가 공백이 있거나없는 "연속적인"의미가 있습니까? – Klaus

+1

@Klaus C++는 공백을 구분하지 않습니다. '>'는 토큰으로 간주되었지만'[['토큰이 없습니다. – Barry

+1

어제 나는'template <> double B :: var = 1.123을 배웠다. '가 잘못되었지만'template <> double B :: var = 1.123;이 작동합니다. 공백 만 ... :-) – Klaus

6

괄호 안에 람다를 넣어야합니다. 그렇지 않으면 컴파일러는 속성을 도입하는 것으로 두 개의 [[을 고려합니다.

연산자 삭제를 사용하면 비슷한 문제가 발생할 수 있습니다. 예를 들어, 당신은 쓸 필요가

delete ([] { return (new int()); }()); 

또는 괄호 안에 람다 묶어야 할 필요가있다

delete [] ([] { return (new int[10]); }()); 

.

+0

을 : 당신이 당신의 의도를 명확하게하기 위해 괄호에 포장 또는 다른 뭔가를해야 할 것이다, 그래서 두 개의 연속 [을 갖는 것은, 특성입니다. 고마워요 – Klaus

1

당신은 괄호

a[ ([](){}) ]; 
+0

지금 처음 아이디어가 여기에 :-) : 좋은 해결 방법을 참조하십시오. 그러나 이것이 표준에 의해 의도 된 아이디어입니까? 속성 시작을 '[['로 고정하면 문제가 제거됩니다. 그게 깨진 구현 또는 "불행한"표준인지 물었습니다. – Klaus