笔记:
从 C++17 开始,没有模板参数的 Foo me;
是合法的。请参阅此答案:https://stackoverflow.com/a/50970942/539997。
适用于 C++17 之前的原始答案:
你所要做的:
Foo<> me;
模板参数必须存在,但您可以将它们留空。
可以将其想象为具有单个默认参数的函数 foo
。表达式 foo
不会调用它,但 foo()
会。参数语法必须仍然存在。这与那是一致的。
使用 C++17,您确实可以。
此功能称为 class template argument deduction,它为您声明模板化类型变量的方式增加了更多灵活性。
所以,
template <typename T = int>
class Foo{};
int main() {
Foo f;
}
现在是 legal C++ code。
你不能这样做,但你可以这样做
typedef Foo<> Fooo;
然后做
Fooo me;
typedef Foo<float> Fooo;
,没有默认类型有什么区别吗?
using Fooo = Foo<>;
您可以使用以下内容:
Foo<> me;
并让 int
成为您的模板参数。尖括号是必须的,不能省略。
有点 不同的情况,但要晚一些,但涉及模板函数。 gcc 11.2 can't seem 编译:
template <typename T = int>
struct Test {};
template<typename T> void foo(T& bar) {}
int main()
{
Test t;
foo<Test>(t);
}
template <typename T = int>
struct Test {};
template<typename T> void foo(T& bar) {}
int main()
{
Test t;
foo<Test<>>(t);
}
当然
template <typename T = int>
struct Test {};
template<typename T> void foo(T& bar) {}
int main()
{
Test t;
foo(t);
}
works - 但有时您需要明确强制类型。这是编译器错误吗?
foo<Test>(t)
),您需要提供 <>对于每个默认模板 - 但是只需放置 foo(t)
就可以了。
根据 C++17
标准,必须传递模板参数。
但是,如果您仍然想要解决此问题,可以使用 using
关键字这样
template <typename T>
class Foo{
};
using IFoo=Foo<int>
或者,您也可以像这样使用 preprocessor
template <typename T>
class Foo{
};
#define IFoo Foo<int>
快速提醒
预处理器不利于调试。
using IFoo=Foo<int>
更糟。宏的忽略命名空间
Foo
might 是模板标识符或 might 是根据是否有默认参数的显式实例化,它会产生一些不必要的复杂性。更好地保留显式实例化语法。可以将其想象为具有单个默认参数的函数foo
。你不能像foo
那样调用它,你用foo()
来调用它。保持这种一致性是有意义的。foo
这样的参数的函数;但是,您可以将不带参数的类命名为Foo
。<>
。查看我的答案以获取更多详细信息。