我想知道类模板和函数模板之间的区别,我应该在哪里使用它们。
答案 0 :(得分:5)
实例化时,类模板成为类,函数模板成为函数。例子:
//Defines a template for a class that can hold two
//objects.
template<typename T1, typename T2>
struct pair {
T1 first;
T2 second;
};
//Defines a template for a function that gives the
//minimum of two values.
template<typename T>
T min(T a, T b) {
return a < b ? a : b;
}
对于普通代码,如果要创建一个由类型参数化的类,则需要使用类模板;如果要创建可以在多种不同类型上操作的函数,则可以使用函数模板。
函数模板也可以进行类型推导,这对于创建工厂函数非常有用:
//Deduces the types of T1 and T2, so
//for example, a pair<int, double> can be created
//by `make_pair(10, 1.2)`
template<typename T1, typename T2>
pair<T1, T2> make_pair(T1&& t1, T2&& t2) {
return {std::forward<T1>(t1), std::forward<T2>(t2)};
}
类模板可用于编写在编译时执行的程序(使用类型作为值,使用模式匹配作为纯函数的模板实例化)。一个简单的例子是这组类模板,它从类型中删除所有const
:
//Removes all `const` from a type, for example:
//`remove_const_recursive<int const*const volatile>::type`
//is the type `int*volatile`.
template<typename T> struct remove_const_recursive { typedef T type; };
template<typename T> struct remove_const_recursive<T const volatile> {
typedef typename remove_const_recursive<T>::type volatile type;
};
template<typename T> struct remove_const_recursive<T volatile> {
typedef typename remove_const_recursive<T>::type volatile type;
};
template<typename T> struct remove_const_recursive<T const> {
typedef typename remove_const_recursive<T>::type type;
};
template<typename T> struct remove_const_recursive<T&> {
typedef typename remove_const_recursive<T>::type& type;
};
template<typename T> struct remove_const_recursive<T*> {
typedef typename remove_const_recursive<T>::type* type;
};
随着您越来越多地使用模板,您将意识到它们可以以多种方式使用。 Expression templates允许您加速某些类型的代码或创建特定于域的语言。 Template metaprogramming和元组可用于自动编写各种繁琐的代码。您可能还会意识到模板的钝语法和有限的性能以及语义能力意味着它们的成本并不总是被它们提供的好处所抵消。
答案 1 :(得分:2)
函数模板尝试从参数类型中推断出特化类型。
当类可以时,函数模板不能部分专门化。
当类可以时,函数模板不能具有默认模板参数。