c++++模板编程中可通过默认参数提升代码简洁性与复用性。1.类模板允许为参数设默认类型,如template

在 C++ 模板编程中,给模板参数设置默认值是一个非常实用的技巧,尤其在类模板和函数模板中。它能让你在使用模板时省去一些重复的类型指定,让代码更简洁。下面我们就来看看类模板和函数模板中默认类型的基本规则和用法。

类模板中的默认类型参数
类模板允许我们为模板参数指定默认类型,这样在实例化类的时候,如果不显式传入类型,就会使用默认类型。
语法格式:

templateclass MyClass { // ... };
在这个例子中,如果创建对象时不指定类型:
MyClass<> obj; // 使用默认类型 int
编译器会自动使用
int作为模板参数。

几点需要注意:
- 默认类型必须放在模板参数列表的最后。
- 可以为多个参数设置默认值,但一旦某个参数有默认值,之后的所有参数都必须有默认值。
- 默认类型可以是基本类型、自定义类型,甚至其他模板类(比如
std::vector
)。
举个更复杂的例子:
templateclass MyMap { // ... }; MyMap<> m1; // Key=int, Value=string MyMap m2; // Key=double, Value=string MyMap m3; // Key=char, Value=float
函数模板中的默认类型参数
相比类模板,函数模板对默认类型的限制要多一些,主要体现在:C++98/03 中不支持函数模板的默认类型参数,直到 C++11 才正式支持。
语法示例:
templateT add(T a, T b) { return a + b; }
调用方式如下:
add(3, 5); // 使用默认类型 double,参数会被推导为 double add(2, 4); // 显式指定类型为 int
注意事项:
- 函数模板的默认类型参数也必须出现在参数列表的末尾。
- 如果函数模板的参数可以通过实参推导出来,那么即使设置了默认类型也不会被使用。
- 有时你可能需要显式写出模板参数来触发默认类型,比如上面的例子中使用
add<>(3,5)
就会强制使用默认类型。
类模板与函数模板默认参数的区别
虽然类模板和函数模板都可以设置默认类型,但它们之间还是有些区别的:
-
类模板:
- 支持默认类型参数。
- 必须显式实例化类模板,因此更容易控制是否使用默认类型。
-
函数模板:
- C++11 开始支持默认类型参数。
- 函数模板的参数常常由实参推导得出,这可能导致默认类型被忽略。
- 有时候需要加
< >
来启用默认类型,例如func<>()
。
实际应用建议
在实际开发中,合理使用默认类型参数可以提升代码的可读性和复用性,但也需要注意以下几点:
- 不要滥用默认类型,特别是当默认类型容易引起歧义或逻辑错误时。
- 对于类模板,默认类型非常适合用于配置型参数,比如容器的分配器(allocator)。
- 对于函数模板,使用默认类型前最好确认是否会影响模板参数推导逻辑。
- 在写库或者通用组件时,适当使用默认类型可以让接口更友好。
基本上就这些了。类模板和函数模板的默认类型机制看起来简单,但在实际使用中还是有一些细节需要注意,尤其是函数模板的参数推导行为可能会掩盖你的默认类型设定。









