在 C++ 中,模板是一种强大的工具,可以帮助我们编写通用的代码,提高代码的重用性和灵活性。模板在函数和/或类的结合下,存在诸多花样,其调用方法也各异,本文将以示例代码的形式抛砖引玉。
函数模板
函数模板是一种通用的函数定义,可以用来创建多个函数版本,以处理不同类型的参数
template <typenameT>
Tadd(Ta, Tb) {
return a + b;
}
voidusing_function_template()
{
// 调用 add<int>(1, 2),返回 3
auto result1 = add<int>(1, 2);
auto result11 = add(1,2);
// 调用 add<double>(1.5, 2.5),返回 4.0
double result2 = add(1.5, 2.5);
}
类模板
类模板允许我们定义通用的类,它可以处理多种不同类型的数据。类模板的语法形式如下:
template <typenameT>
classPair {
private:
T first;
T second;
public:
Pair(Tf, Ts) : first(f), second(s) {}
};
voidusing_class_template()
{
Pair<int> p1(1, 2);
Pair p1(1, 2);//大于等于C++17, CTAD
Pair<double> p2(1.5, 2.5);
}
之前的C++版本中,模板类,声明对象时要指定其类型;C++17后,拥有了CTAD(之前浅析CTAD中有提到过),可以由编译器自动推导。
普通类的模板成员函数
在普通类中,可以定义成员函数模板,这些成员函数模板可以接受不同类型的参数。
classMyClass {
public:
// 成员函数模板
template <typenameT>
voidprint(Tvalue) {
std::cout << "Value: " << value << std::endl;
}
};
intusing_normal_class_function_template() {
MyClass obj;
obj.print<int>(5);
obj.print(5.5);
obj.print("Hello");
return0;
}
普通类的模板函数调用,可以类比模板函数的调用,只是类的模板函数调用是基于对象的。
类模板的成员函数
类模板的成员函数可以是普通的成员函数,也可以是成员函数模板。例如,我们可以为上面的 Pair 类添加一个成员函数模板来比较两个键值对的大小:
template <typenameT>
classPair {
private:
T first;
T second;
public:
Pair(Tf, Ts) : first(f), second(s) {}
//普通成员函数
TgetFirst() const { return first; }
TgetSecond() const { return second; }
//模板成员函数
template<typenameU>
boolIsFirstEqual(Uu)
{
return (u==first)?true:false;
}
};
voidusing_calss_template_functions()
{
Pair<int> p{3,4};
//普通成员函数
//直接调用即可
p.getFirst();
//模板成员函数
//调用函数需要主动指定类型或有编译器推导
p.IsFirstEqual<double>(3.0);
}
在上面的例子中,针对模板类分别定义了其普通成员函数和模板成员函数,使用模板类声明对象后,依次调用了其普通成员函数和模板成员函数。
总结
本文列举了模板函数和/或模板类的使用案例。以代码示例的形式说明了函数模板、类模板、普通成员函数、模板成员函数的使用方法。