模板默认参数

use*_*658 134 c++ templates

如果我被允许做以下事情:

template <typename T = int>
class Foo{
};
Run Code Online (Sandbox Code Playgroud)

为什么我不允许在主要方面做以下事情?

Foo me;
Run Code Online (Sandbox Code Playgroud)

但我必须指明以下内容:

Foo<int> me;
Run Code Online (Sandbox Code Playgroud)

C++ 11引入了默认模板参数,现在它们对我完全理解是难以理解的.

Jos*_*eld 166

你必须做:

Foo<> me;
Run Code Online (Sandbox Code Playgroud)

必须存在模板参数,但您可以将它们留空.

可以把它想象成foo具有单个默认参数的函数.表达式foo不会调用它,但foo()会调用它.参数语法必须仍然存在.这与此一致.

  • @OlafDietsche但你不能拥有一个模板类和一个具有相同名称的非模板类,因此编译器应该能够通过查看名称来决定. (18认同)
  • 我一直想知道为什么`<>`是必要的.任何的想法? (16认同)
  • @Pubby我猜,标准委员会也问自己.现在,使用C++ 17,在这种情况下不再需要`<>`.查看我的答案以获取更多详细信息. (5认同)
  • @Pubby我想如果`Foo`*可能*是模板标识符,或者*可能*是一个显式实例,取决于是否有默认参数,它会产生一些不必要的复杂性.更好地保留显式实例化语法.可以把它想象成一个带有单个默认参数的函数`foo`.你不能把它称为`foo`,用`foo()`来称呼它.保持这种一致性是有道理的. (4认同)
  • @aschepler使用函数,可以从函数参数推导出模板参数.对于类,无法确定是指具有默认参数的模板类还是非模板类. (4认同)
  • @sftrabbit 但你也不能调用像 `foo` 这样没有参数的函数;但是,您可以将没有参数的类命名为 `Foo`。 (3认同)

Pao*_*o M 40

使用C++ 17,你的确可以.

此功能称为类模板参数推导,并为您声明模板化类型的变量提供了更多灵活性.

所以,

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

int main() {
    Foo f;
}
Run Code Online (Sandbox Code Playgroud)

现在是合法的C++代码.

  • 这应该是最佳答案 - 最佳答案已经过时了。 (5认同)
  • 奇怪。刚在我的C ++ 17项目中尝试过,但没有成功:“模板占位符类型'const MyType'必须后跟一个简单的声明符id”。我正在使用GCC 7.3.0。 (4认同)
  • @PaoloM 哦,酷,很高兴知道这只是编译器版本问题。感谢您查看这个。 (2认同)

And*_*owl 18

您可以使用以下内容:

Foo<> me;
Run Code Online (Sandbox Code Playgroud)

并且int是你的模板参数.角括号是必要的,不能省略.


g24*_*24l 17

你不能这样做,但你可以做到这一点

typedef Foo<> Fooo;
Run Code Online (Sandbox Code Playgroud)

然后呢

Fooo me;
Run Code Online (Sandbox Code Playgroud)

  • C++11-ish 的方式是说`使用 Foo = Foo&lt;&gt;;` (10认同)