c++ - Calling `this` member function from generic lambda - clang vs gcc -


issue: passing generic lambda (to template function) captures this , calls member function of this without explicit this-> not compile on gcc. if lambda not generic, or if lambda not passed other function called in place, compiles withoit explicit this->. clang cool code in situations.

time round of clang vs gcc. who's right?

wandbox example


template<typename tf> void call(tf&& f) {     f(1);    }  struct example {             void foo(int){ }      void bar()     {         call([this](auto x){ foo(x); });     } };  int main() {     example{}.bar();     return 0; } 

  • with bar() = call([this](auto x){ foo(x); });
    • clang++ 3.6+ compiles.
    • g++ 5.2+ does not compile.

      error: cannot call member function 'void example::foo(int)' without object call([this](auto x){ foo(x); });`


  • with bar() = call([this](auto x){ this->foo(x); });
    • clang++ 3.6+ compiles.
    • g++ 5.2+ compiles.

  • with bar() = call([this](int x){ foo(x); });
    • clang++ 3.6+ compiles.
    • g++ 5.2+ compiles.

  • with bar() = [this](auto x){ foo(x); }(1);
    • clang++ 3.6+ compiles.
    • g++ 5.2+ compiles.

why this-> necessary in case of generic lambda?

why this-> not necessary if lambda isn't passed call?

who being non standard-compliant?

this gcc bug. [expr.prim.lambda]:

the lambda-expression’s compound-statement yields function-body (8.4) of function call operator, purposes of name lookup (3.4), determining type , value of this (9.3.2) , transforming id-expressions referring non-static class members class member access expressions using (*this) (9.3.1), compound-statement considered in context of lambda-expression. [ example:

struct s1 {     int x, y;     int operator()(int);     void f() {         [=]()->int {             return operator()(this->x + y);                  // equivalent s1::operator()(this->x + (*this).y)                 // has type s1*         };     } }; 

—end example ]

since in example capture this, name lookup should include class members of example, should therefore find example::foo. lookup performed identical happen if foo(x) appeared in context of lambda-expression itself, if code looked like:

void bar() {     foo(x); // example::foo(x); } 

at least bug has simple workaround indicated in question: this->foo(x);.


Comments

Popular posts from this blog

html - Firefox flex bug applied to buttons? -

html - Missing border-right in select on Firefox -

c# - two queries in same method -