【问题标题】:Why is <> required when specifying a template class which has defaults for all its template parameters?为什么在指定所有模板参数都具有默认值的模板类时需要 <>?
【发布时间】:2017-03-08 11:30:08
【问题描述】:

在指定所有模板参数都具有默认值的模板类时,为什么需要&lt;&gt; 有充分的理由吗?

例如

#include <iostream>

template<typename T = int>
class C {
public:
    T obj = 0;
};

int main()
{
    C c1; // Error on almost all compilers (see note below)
    C<> c2;
    std::cout << c1.obj << " " << c2.obj << std::endl;
    return 0;
}

这样做的一个缺点是,如果你有一个已经在不同地方使用过的类,然后你将它重构为一个类模板,它的模板参数具有默认参数,那么你必须在其中添加 &lt;&gt;所有使用该类的地方。

注意:它看起来像 GCC 最新的 HEAD (7.0.1) accepts 没有&lt;&gt; 的语法。早期版本没有,任何版本的 Clang 也没有。这是最新的 GCC HEAD 中的错误吗?或者也许 C++17 的标准现在接受没有 &lt;&gt; 的语法,而 GCC 就在前面?

【问题讨论】:

  • C c1{}; 在最新的 clang 上编译。
  • This answer 解释了为什么需要&lt;&gt; - 简而言之,这是为了避免模板和类型之间的歧义。
  • "或者也许 C++17 的标准现在接受不带 " 的语法,在 C++17 中有类模板推导发生在这里
  • @PiotrSkotnicki 欢迎作为答案发布。
  • @Danra 但我不知道之前不允许模板名称作为类型说明符的确切原因(除了原因)

标签: c++ templates c++17


【解决方案1】:

在 C++17 中,这是格式良好的:

C c1{};

由于deduction for class templates。我们将为每个构造函数(和推导指南)综合一个函数并执行重载决议:

template <class T=int> C<T> foo();
template <class T=int> C<T> foo(C<T> const&);
template <class T=int> C<T> foo(C<T>&&);

第一个是可行的重载,另外两个不是,所以推演成功,占位符C替换为推导类型C&lt;int&gt;

然而,在语法上,初始化器在 [dcl.type.class.deduct] 中是必需的

如果推导类类型的占位符在 simple-declarationdecl-specifier-seq 中显示为 decl-specifier ,该声明的 init-declarator 应采用以下形式:

declarator-id attribute-specifier-seqoptinitializer

占位符被类的重载决议选择的函数的返回类型替换 模板推演(13.3.1.8)。

但是C c; 不包含初始化器,所以它不符合语法。这是允许这样做的 gcc 错误。虽然特别禁止这样做似乎很奇怪。 显然,这个限制在 Kona 中已经解除,所以 C c; 在 C++17 中确实是格式良好的。一旦出现新的措辞,我会更新答案。


在 C++17 之前,该语句的格式错误仅仅是因为 C 不是类型。 CC&lt;&gt; 不是一回事。有所有默认模板参数,现在仍然没有特殊考虑。类型和类模板是不同的,并且继续被区别对待。

【讨论】:

  • 根据en.cppreference.com/w/cpp/language/class_template_deduction 对变量声明的推论只应在“使用直接带括号或花括号的初始化程序”时发生,所以也许最新的 Clang 是正确的,不接受C c1;,而只接受C c1{};,最新的 GCC 也接受前者是错误的。
  • @Danra 显然上周在 Kona 中解除了初始化限制,所以 C c; 确实有效。
  • 你在哪里知道初始化器要求被删除了?只是好奇。
  • @ThomasMcLeod 在 Kona 后邮件发出时寻找纸张 P0620R0
猜你喜欢
  • 2012-09-27
  • 2011-10-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-29
  • 1970-01-01
  • 2019-01-09
  • 2016-03-22
  • 2018-10-12
相关资源
最近更新 更多