c++ - 从通用 lambda 调用 `this` 成员函数 - clang vs gcc

标签 c++ lambda this language-lawyer c++14

问题: 传递一个通用 lambda(到模板函数),该 lambda 捕获 this 并调用 this< 的成员函数 没有明确的 this-> 不会在 gcc 上编译。如果 lambda 不是通用的,或者如果 lambda 没有传递给任何其他函数而是就地调用,那么它会在没有显式 this-> 的情况下进行编译。在所有情况下,Clang 的代码都很酷。

又是一轮clang vs gcc的时间了。谁是对的?

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+ 编译
    • 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/

相关文章:

c# - 尝试使用mongodb的filter.near

Lambda微积分运算符优先级

coffeescript - CoffeeScript:如何同时使用粗箭头和该箭头?

c++ - const 成员函数中指向 this 的非常量指针

c++ - 从 unordered_map 存储和检索后对象发生变化

c++ - 删除和移动数组 C++ 中的剩余元素

c++ - Variadic 模板递归返回类型推导编译错误

c++ - 如何对齐 2d 数组元素以形成 3*3 矩阵?

haskell - 这个haskell函数中的这些值来自哪里?

java - 如何在回收器适配器类中使用 getcontext()?