具有非静态lambda成员的类不能使用默认模板参数?

时间:2012-10-01 05:39:31

标签: c++ gcc lambda c++11

这个小测试程序:

#include <functional>

//template<class T>            // <-- with this, gcc compiles  ok
template<class T=void>
struct  c{
        std::function<int(int)> f = [](int i){return i+i;};
};

int main() {};

Clang-3.2编译好了,但是从GCC 4.7.1和4.8我得到了奇怪的错误:

t.cc:6:31: error: default argument for template parameter for class enclosing ‘struct __lambda0’
  function<int(int)> f = [](int i){return i+i;};
                               ^

这是那些模糊不清的C ++规则中没有人知道的异常,还是GCC错误?

修改 看起来像个bug。我已经提交了bug report

2 个答案:

答案 0 :(得分:4)

我认为这是一个默认成员初始化的g ++错误。我对此并不乐观,所以有以下支持证据:

template<class T=void>
struct  c {
   std::function<int(int)> f;
   c() : f([](int i){return i+i;}) {
   }
};

int main() {}

如果有效,那么你所做的也应该有效。即使你构建了一个c

也是如此

就个人而言,我认为应该谨慎使用默认成员初始化。我认为很容易与它产生很多混淆,因为大多数人都希望所有的初始化都在构造函数中完成,而成员初始化器不一定在任何构造函数附近。因此,他们可能会让某些人不知道某个成员如何获得特定价值。

我可以看到案例,特别是对于简单的,主要是数据类,它可以很好地工作。但大多数情况下,我认为如果你有一个任何类型的构造函数体,你可能不应该使用默认成员初始化。

答案 1 :(得分:0)

此代码无论如何都会在gcc上出错。是的,没有默认参数就可以编译。它可以编译,因为struct c不在任何地方使用。但是如果你试图创建这个结构的实例,你就会收到错误。

#include <functional>

template<class T>
struct c {
    std::function<int(int)> f = [](int i){return i+i;};
};

int main() {
    c<int> _c; // error
}

它看起来像gcc的错误。这种方式可以帮助避免问题。

#include <functional>
#include <iostream>

template<class T=void>
struct c {
   c() : f([](int i){return i+i;}) {
   }

   std::function<int(int)> f;
};

int main() {
   c<> _c; 
   std::cout << _c.f(10) << std::endl;
}
相关问题