这个小测试程序:
#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
答案 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;
}