【问题标题】:GCC compilation error when using template class method inside lambda expression在 lambda 表达式中使用模板类方法时出现 GCC 编译错误
【发布时间】:2013-04-07 03:14:28
【问题描述】:

以下代码在 gcc 4.6.3 中编译失败,而在 clang 3.1 中编译完美(我提供了 DummyMath 类的两个版本,都表现出相同的问题):

#include <iostream>
using namespace std;

//* // To swap versions, comment the first slash.

// ===============================================
// V1
// ===============================================
template <typename T>
class DummyMath
{
public:
    T sum(T a1, T a2);
    T mult(T a1, int n);
};

template <typename T>
T DummyMath<T>::sum(T a1, T a2)
{
    return a1 + a2;
}

template <typename T>
T DummyMath<T>::mult(T a1, int n)
{
    auto x2 = [this](T a1) -> T
    {
        return sum(a1, a1); // <------- gcc will say that "sum" was not declared in this scope! 
    };

    T result = 0;
    n = n/2;
    for(int i = 0; i < n; ++i)
        result += x2(a1);
    return result;
}
/*/
// ===============================================
// V2
// ===============================================
template <typename T>
class DummyMath
{
public:
    T sum(T a1, T a2)
    {
        return a1 + a2;
    }

    T mult(T a1, int n)
    {
        auto x2 = [this](T a1) -> T {
            return sum(a1, a1);
        };

        T result = 0;
        n = n/2;
        for(int i = 0; i < n; ++i)
            result += x2(a1);
        return result;
    }
};
//*/

int main()
{
    DummyMath<float> math;
    cout << math.mult(2.f, 4) << endl;

    return 0;
}

错误是:

main.cpp:25:20: error: ‘sum’ was not declared in this scope

DummyMath 类的两个版本(V1 和 V2)在 gcc 中都失败了,并且在 clang 中都成功了。这是 GCC 中的错误吗?

谢谢。

【问题讨论】:

  • 如果你把它改写成return DummyMath&lt;T&gt;::sum(a1, a1);这样的东西会起作用吗?
  • 确实有效,先生。
  • gcc4.7.2 这里有一个内部编译器错误,这绝对是一个错误。所以 4.6.3 中可能也有一个错误。

标签: c++ templates gcc c++11 clang


【解决方案1】:

这是来自 gcc 4.7.2 的已知错误(参见 question)。编译器识别出 this 指针将被捕获,并且生成的闭包确实包含一个指向它的指针,但该指针没有在闭包的构造函数中初始化。

您可以使用return this-&gt;sum(a1, a2); 让它工作。在LiveWorkSpace 上运行您的示例,表明这对于 gcc >= 4.7.3 以及 Clang 3.2 和 Intel 13.0.1(即打印 8 作为输出)是固定的。

C++11 支持变化很大,最好尽快升级到您喜欢的编译器的最新版本。不幸的是,大多数 Linux 发行版都提供了 gcc 4.7.2 的打包版本,而 gcc 4.8.0 还没有。您可能需要从源代码编译它们。

【讨论】:

  • gcc 5.4 也有这个错误。您建议的修复解决了它。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多