模板默认参数


151

如果允许我执行以下操作:

template <typename T = int>
class Foo{
};

为什么不允许我主要执行以下操作?

Foo me;

但我必须指定以下内容:

Foo<int> me;

C ++ 11引入了默认模板参数,现在我无法完全理解它们了。

Answers:


188

你所要做的:

Foo<> me;

模板参数必须存在,但您可以将其保留为空。

可以将其视为foo具有单个默认参数的函数。该表达式foo不会调用它,但是foo()会调用它。参数语法必须仍然存在。与此相符。


4
@Pubby我想这可能会带来一些不必要的复杂性,如果它Foo 可能是模板标识符或可能是显式实例化(取决于是否有默认参数)。最好保留显式实例化语法。可以将其视为foo具有单个默认参数的函数。您不能像那样称呼它foo,而要用来称呼它foo()。保持一致是有意义的。
约瑟夫·曼斯菲尔德

2
@sftrabbit,但是您不能像这样调用没有参数的函数foo;您可以命名一个没有参数的类Foo
赛斯·卡内基

4
@aschepler通过函数,可以从函数参数推导出模板参数。对于类,无法决定是要使用默认参数的模板类,还是要使用非模板类。
Olaf Dietsche 2013年

21
@OlafDietsche,但是您不能具有相同名称的模板类和非模板类,因此编译器应该能够仅通过查看名称来决定。
赛斯·卡内基

7
@Pubby我想标准委员会也问过同样的问题。现在,对于C ++ 17,<>在这种情况下不再需要。查看我的答案以获取更多详细信息。
Paolo M

53

使用C ++ 17,您确实可以。

此功能称为类模板参数推导,它为声明模板化类型的变量的方式增加了灵活性。

所以,

template <typename T = int>
class Foo{};

int main() {
    Foo f;
}

现在是合法的C ++代码


5
奇怪。刚刚在我的C ++ 17项目中尝试过,但没有成功:“模板占位符类型'const MyType'必须后跟一个简单的声明符id”。我正在使用GCC 7.3.0。
Silicomancer

1
@Silicomancer不看代码和命令行就很难说...也许您正在处理像这里的指针?
Paolo M


1
@Borgleader显然,Coliru使用的是clang 5.0。以此判断,它应该支持C ++ 17模板参数推导,但显然id不支持。如果您使用clang 7.0 在wandbox中尝试相同的示例,那么它可以完美地工作。
Paolo M

2
@PaoloM太好了,很高兴知道它只是编译器版本问题。感谢您查看这个。
Borgleader19年

19

您不可以这样做,但是您可以这样做

typedef Foo<> Fooo;

然后做

Fooo me;

有默认类型和:typedef Foo<float> Fooo;,没有默认类型有什么区别吗?
qrikko '16

5
用C ++ 11表示的方式是说using Fooo = Foo<>;
Adrian W

18

您可以使用以下内容:

Foo<> me;

int成为您的模板参数。尖括号是必要的,不能省略。


有意义并谢谢您,但是,如下所述,为什么指定的类型存在?
user633658 2013年

@ user633658:您的意思是“类型说明符”吗?我不确定我是否了解
Andy Prowl

无论如何,关于需要使用空尖括号的原因,我只能作一个猜测,它们都是为了排除仅使用模板名称的可能歧义,但是我不得不承认我不知道确切的含义。原因
Andy Prowl

我强烈怀疑<>的要求是使编译器的解析器能够确定您所引用的是称为foo的模板化类,而不是其他称为foo的类。
Mac
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.