为什么在指定其所有模板参数具有默认值的模板类时需要<>?

Why is <> required when specifying a template class which has defaults for all its template parameters?

本文关键字:gt lt 默认值 为什么 参数      更新时间:2023-10-16

当指定具有所有模板参数默认值的模板类时,是否需要<>

,例如

#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;
}

一个示例的缺点是,如果您有一个已经在各个地方使用的类,然后重构它为具有默认参数的类模板,则必须在所有模板参数中添加<>使用班级的地方。

注意:看起来GCC最新的头(7.0.1)接受没有<>的语法。较早的版本不会,也没有任何版本的clang。这是最新的海湾合作委员会负责人的错误吗?或者也许C 17的标准现在接受没有<>的语法,而GCC就在这里?

在C 17中,这是很好的:

C c1{};

由于扣除了类模板。我们将为每个构造函数(和扣除指南)合成一个函数,并执行超载分辨率:

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<int>代替。

然而,从语法上讲,初始化器在[dcl.type.class.deduct]中 ]:

如果推论类类型的占位符在 ext-specifier-seq simple-> simple-declaration dect-specifier 中出现,该声明的 init-declarator 应为形式:

dectarator-id 属性 - seq-seq opt initializer

占位符被替代的函数的返回类型由Orderload分辨率用于类 模板扣除(13.3.1.8)。

,但是C c;包含 initializer ,因此语法不合格。这是一个允许此问题的GCC错误。尽管特别禁止这样做似乎很奇怪。显然,在科纳(Kona)取消了这一限制,因此C c;在C 17中确实会得到很好的形式。一旦新措辞出来,我将更新答案。


在C 17之前,该语句仅仅是因为C不是类型。CC<>不是同一回事。对于拥有所有默认模板参数,并且仍然没有特殊的考虑。类型和类模板是不同的,并且继续对待不同的对待。