【问题标题】:Difference between adding and omitting template parameter for class name inside constructor在构造函数中为类名添加和省略模板参数之间的区别
【发布时间】:2016-11-12 14:46:01
【问题描述】:

我想知道两者之间是否有本质区别:

template <typename T> 
class foo{
  foo<T>(){};
};

template<typename T>
class foo{
  foo(){};
};

两者似乎都有效,但我不明白两者之间的区别。第一个让我很困惑,我不明白在这里的作用是什么。

【问题讨论】:

    标签: c++ templates constructor typename injected-class-name


    【解决方案1】:

    根据injected-class-name的规则,它们完全是一回事。

    $14.6.1/1 Locally declared names [temp.local]:

    与普通(非模板)类一样,类模板有一个 注入类名称(子句 [类])。注入的类名可以是 用作模板名称或类型名称。当它与一个 模板参数列表,作为模板的模板参数 模板参数,或作为最终标识符 友元类模板声明的详细类型说明符,它 指类模板本身。否则等价于 模板名称后跟类的模板参数 .

    中包含的模板

    所以foofoo&lt;T&gt; 在这里指的是同一个东西。更具体地说,

    第一个让我很困惑,我不明白在这里的作用是什么。

    您正在使用注入类名称foo 及其模板参数T(即foo&lt;T&gt;),它引用模板类本身。

    【讨论】:

      【解决方案2】:

      请注意,从 C++20 开始,较长的形式不再有效,您必须使用依赖于 injected-class-name 的较短形式。

      [diff.cpp17]#class-2:

      simple-template-id 不再作为构造函数或析构函数的 declarator-id 有效

      在规范中使用以下示例:

      template<class T>
      struct A {
        A<T>();           // error: simple-template-id not allowed for constructor
        A(int);           // OK, injected-class-name used
        ~A<T>();          // error: simple-template-id not allowed for destructor
      };
      

      确实是 GCC 主干版本 rejects code using the longer form(而 Clang 11 和 GCC 10.2 still accepts it)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-02-23
        • 1970-01-01
        • 1970-01-01
        • 2012-08-25
        • 2021-06-24
        • 1970-01-01
        相关资源
        最近更新 更多