template <typename T1, typename T2, typename RT = decltype(T1() + T2())>
RT smartAdd(const T1& a, const T2& b) {
return a + b;
}
// 使用示例
auto result = smartAdd(3, 4.5); // 自动推导为double
该函数模板的参数声明,包含三个部分:
T1
- 第一个类型参数T2
- 第二个类型参数RT
- 返回类型,默认值为 decltype(T1() + T2())
的结果decltype
关键字decltype
(declare type) 是C++11引入的类型推导关键字:
decltype(expression)
示例:
int a = 5;
decltype(a) b; // b的类型是int
T1()
和 T2()
的含义这是创建临时对象的值初始化(value initialization):
T1()
- 创建T1类型的临时对象T2()
- 创建T2类型的临时对象示例等价代码:
T1 temp1 = T1(); // 值初始化
T2 temp2 = T2(); // 值初始化
T1() + T2()
表达式示例场景:
int + double
→ double
string + const char*
→ string
Matrix + Vector
→ 取决于运算符重载typename RT = decltype(T1() + T2())
表示:
考虑这个完整函数模板:
template <typename T1, typename T2, typename RT = decltype(T1() + T2())>
RT add(const T1& a, const T2& b) {
return a + b;
}
使用场景:
auto r1 = add(3, 4.5); // RT推导为double
auto r2 = add(string("Hello"), " World"); // RT推导为string
// 显式指定RT会覆盖默认推导
auto r3 = add<int, double, float>(5, 3.2); // RT强制为float
在C++11之前,很难自动推导运算结果的准确类型,通常需要:
template <typename T1, typename T2>
auto add(T1 a, T2 b) -> decltype(a + b) {
return a + b;
}
// C++14简化版
template <typename T1, typename T2>
auto add(T1 a, T2 b) {
return a + b;
}
template <typename T1, typename T2>
requires requires(T1 a, T2 b) { a + b; } // 约束必须有+运算符
auto add(T1 a, T2 b) {
return a + b;
}
template <typename Container>
using ValueType = decltype(*std::declval<Container>().begin());
template <typename T>
auto print(const T& val) -> decltype(cout << val, void()) {
cout << val;
}
C++14后可以用更简洁的方式实现相同功能:
template <typename T1, typename T2>
auto smartAdd(const T1& a, const T2& b) {
return a + b;
}
typename RT = decltype(T1() + T2())
是模板元编程中的一种强大技术,它:
这种模式在数值计算、运算符重载、泛型算法等场景中非常有用,是现代C++编写灵活且类型安全代码的重要技术。