问题: 传递一个通用 lambda(到模板函数),该 lambda 捕获 this
并调用 this< 的成员函数
没有明确的 this->
不会在 gcc 上编译。如果 lambda 不是通用的,或者如果 lambda 没有传递给任何其他函数而是就地调用,那么它会在没有显式 this->
的情况下进行编译。在所有情况下,Clang 的代码都很酷。
又是一轮clang vs gcc的时间了。谁是对的?
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+ 编译。
- g++ 5.2+ 无法编译。
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+ 编译。
- g++ 5.2+ 编译。
- With
bar()
=call([this](int x){ foo(x); });
- clang++ 3.6+ 编译。
- g++ 5.2+ 编译。
- With
bar()
=[this](auto x){ foo(x); }(1);
- clang++ 3.6+ 编译。
- g++ 5.2+ 编译。
为什么 this->
只有在泛型 lambda 的情况下才需要?
如果没有将 lambda 传递给 call
,为什么不需要 this->
?
谁不符合标准?
最佳答案
这是一个 gcc 错误。来自 [expr.prim.lambda]:
The lambda-expression’s compound-statement yields the function-body (8.4) of the function call operator, but for purposes of name lookup (3.4), determining the type and value of
this
(9.3.2) and transforming id-expressions referring to non-static class members into class member access expressions using(*this)
(9.3.1), the compound-statement is considered in the context of the lambda-expression. [ Example:struct S1 { int x, y; int operator()(int); void f() { [=]()->int { return operator()(this->x + y); // equivalent to S1::operator()(this->x + (*this).y) // this has type S1* }; } };
—end example ]
由于您在示例中捕获了 this
,因此名称查找应该包括 Example
的类成员,因此应该找到 Example::foo
.执行的查找与如果 foo(x)
出现在 lambda-expression 本身的上下文中会发生的情况相同,即如果代码看起来像:
void bar()
{
foo(x); // clearly Example::foo(x);
}
至少这个错误有一个非常简单的解决方法,如问题所示:只需执行 this->foo(x);
。
关于c++ - 从通用 lambda 调用 `this` 成员函数 - clang vs gcc,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32097759/