从泛型lambda调用`this`成员函数 - clang vs gcc

Vit*_*meo 38 c++ lambda this language-lawyer c++14

问题:传递一个普通的lambda (到一个模板函数),它捕获this并调用一个this没有显式的成员函数,this->不能在gcc上编译.如果lambda不是通用的,或者lambda没有被传递给任何其他函数但是就地调用,那么它将编译为withoit this->.在所有情况下,Clang都很酷.

时间又一轮的铛VS GCC.谁是对的?

Wandbox示例


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); });
    • clang ++ 3.6+ 编译.
    • g ++ 5.2+ 无法编译.

      错误:无法调用成员函数'void Example :: foo(int)'没有对象调用([this](auto x){foo(x);});`


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

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

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

为什么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表达式的上下文中考虑复合语句.[例如:

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*
        };
    }
};
Run Code Online (Sandbox Code Playgroud)

- 末端的例子]

因为在您捕获的示例中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);.