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?
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
Post a Comment