Vit*_*meo 38 c++ lambda this language-lawyer c++14
问题:传递一个普通的lambda (到一个模板函数),它捕获this并调用一个this没有显式的成员函数,this->不能在gcc上编译.如果lambda不是通用的,或者lambda没有被传递给任何其他函数但是就地调用,那么它将编译为withoit this->.在所有情况下,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;
}
Run Code Online (Sandbox Code Playgroud)
bar()=call([this](auto x){ foo(x); });
错误:无法调用成员函数'void Example :: foo(int)'没有对象调用([this](auto x){foo(x);});`
bar()=call([this](auto x){ this->foo(x); });
bar()=call([this](int x){ foo(x); });
bar()=[this](auto x){ foo(x); }(1);
为什么this->只有在通用lambda的情况下才需要?
this->如果没有传递lambda,为什么不必要call?
谁不符合标准?
Bar*_*rry 18
这是一个gcc bug.来自[expr.prim.lambda]:
所述λ-表达的化合物语句产生的功能体的函数调用操作的(8.4),但对于名称查找的目的(3.4),确定的类型和值
this(9.3.2)和转化ID表达式 参照使用(*this)(9.3.1)将非静态类成员转换为类成员访问表达式,在lambda表达式的上下文中考虑复合语句.[例如:Run Code Online (Sandbox Code Playgroud)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* }; } };- 末端的例子]
因为在您捕获的示例中this,名称查找应该包括Example应该找到的类成员Example::foo.执行的查找与foo(x)在lambda表达式本身的上下文中出现的情况相同,即代码如下所示:
void bar()
{
foo(x); // clearly Example::foo(x);
}
Run Code Online (Sandbox Code Playgroud)
至少这个bug有一个非常简单的解决方法,如问题所示:只是这样做this->foo(x);.