c++ - 当包含方括号时,默认构造函数不会在模板类中编译 (g++4.6.1)

标签 c++ templates g++ default-constructor

我在 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/

相关文章:

c++ - 没有动态分配的哈希表/映射实现

c++ - 重载 operator<< 以接受模板函数

python - 当使用超过 1 个参数时,Flask jinja 模板无法识别 css

c++ - 对 C++ 中范围解析运算符的困惑

gcc - 在具有 32 位用户空间的 64 位系统上,Configure 无法检测到正确的 ld

c++ - 如何在 Eclipse CDT 中配置特定的 GCC 交叉工具链?

c++ - 尽管使用不存在的成员程序编译

c++ - 尝试创建共享库时出现 C/C++ 错误。制作库的静态版本时不会出现错误

c++ - 如何让 NetBeans 使用 C++11

c++ - 如何避免在多个文件中重新包含 <iostream>?