在 C++ 中,类模板和函数模板是用来创建通用类型的模板,允许在编写代码时将类型参数化。这种泛型编程方式可以帮助我们编写更通用、更灵活的代码,提高代码的重用性和可维护性。
类模板(Class Templates)
类模板允许在类定义中使用一个或多个类型参数,用于创建通用的类。
template <typename T>
class MyTemplate {
public:T data;MyTemplate(T d) : data(d) void printData() {std::cout << "Data: " << data << std::endl;}
};实例化:通过为类型参数提供具体的类型,可以实例化类模板。MyTemplate<int> intTemplate(42);
MyTemplate<std::string> strTemplate("Hello");
- 多个类型参数:类模板可以接受一个以上的类型参数。
template <typename T, typename U>
class Pair {
public: T first; U second;Pair(T f, U s) : first(f), second(s)
};
2. 成员函数模板:类模板内部的成员函数也可以是函数模板。
template <typename T>
class MyTemplate {
public:T data;MyTemplate(T d) : data(d) template <typename U>void printAndAdd(U value) {std::cout << "Data: " << data << std::endl;std::cout << "Sum: " << data + value << std::endl;}
};
函数模板(Function Templates)
函数模板允许定义通用的函数,可以接受不同类型的参数。
template <typename T>
T add(T a, T b) {return a + b;
}实例化:通过在调用时提供具体的类型,可以实例化函数模板。int sum = add(3, 5); // 实例化为 add<int>(3, 5)
double result = add(2.5, 3.7); // 实例化为 add<double>(2.5, 3.7)
非类型参数:函数模板可以接受非类型参数,比如整数或指针。
template <typename T, int N>
T multiplyByN(T value) {return value * N;
}
这个例子中,multiplyByN 是一个函数模板,接受一个值和一个整数作为参数,并将值乘以整数。
函数模板特化:可以为函数模板提供特定类型的实现,称为函数模板特化。
template <>
std::string add<std::string>(std::string a, std::string b) {return a + " " + b;
}
类型推断:在函数调用时,编译器通常能够推断函数模板的类型参数,无需显式指定类型。
int sum = add(3, 5); // 编译器推断为 add<int>(3, 5)
在这个例子中,编译器会根据传入的参数类型推断函数模板的类型参数,无需显式指定类型。
int main() {int sum = add(3, 5); // 实例化为 add<int>(3, 5)double result = add(2.5, 3.7); // 实例化为 add<double>(2.5, 3.7)int multiplied = multiplyByN<int, 3>(4); // 实例化为 multiplyByN<int, 3>(4)std::string concat = add("Hello", "World"); // 实例化为 add<std::string>("Hello", "World")return 0;
}
区别
1. 作用范围:类模板用于创建通用的类,而函数模板用于创建通用的函数。
2. 类型参数位置:对于类模板,类型参数写在类名后面;对于函数模板,类型参数写在函数名后面。
3. 实例化方式:类模板的实例化需要在定义类对象时提供具体的类型;函数模板的实例化可以通过函数调用时推断类型或显式指定类型。