我在 Google 上找不到任何关于此的信息,在以下示例中:
#include <iostream>
class Default
{
public:
void Print()
{
std::cout << "This is a message\n";
}
};
template <class C = Default>
class Template
{
public:
static void Test()
{
Default oDefault();
}
};
int main()
{
return 0;
}
代码编译失败并出现错误:
In static member function ‘static void Template::Test()’: 19:22: error: default template arguments may not be used in function templates without -std=c++0x or -std=gnu++0x
问题是它不喜欢那行出现的括号,我不明白为什么。如果我删除括号,代码编译就好了。此外,如果我删除模板声明(第 13 行),它也可以正常编译。这是一个错误还是关于这种情况的某处有一些规则?
我正在使用 g++4.6.1(gcc 版本 4.6.1(Ubuntu/Linaro 4.6.1-9ubuntu3))
最佳答案
将其更改为:
Default oDefault = Default(); // Version 1
尽管您可以使用:
Default oDefault; // Version 2
这有一个稍微不同的意思。
- 版本 1:使 POD 成员初始化为零(在某些情况下)。
- 版本 2:导致 POD 成员未初始化(在某些情况下)。
通过版本 1 看起来它调用了一个额外的拷贝构造,但事实并非如此(在大多数编译器中),因为额外的拷贝将被编译器省略,并且将发生一个简单的正常(零初始化)构造。
您应该更喜欢零初始化而不是默认值(通常),就好像该类(或任何成员类型)没有用户定义的构造函数(如默认值)那么区别在于默认初始化使 POD 成员未定义而零-initialized 将 POD 成员初始化为零。现在你可能认为我的类(class)没有成员所以没关系。但是如果你修改类会发生什么,你会去寻找所有实例并更新它们吗?最好使用版本一,让编译器做正确的事情。
有关所有令人兴奋的细节,请参阅:
您的初始版本不起作用的原因是它实际上是一个函数的前向声明。这是由 C++ 的复杂语法引起的,这只是您需要记住的规则之一。您可以将其视为“最令人烦恼的解析”。
关于c++ - 当包含方括号时,默认构造函数不会在模板类中编译 (g++4.6.1),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9764905/