函数模板的用法,以及类外定义的注意事项

先来个例子:

 1 #include <iostream>
 2 
 3 using namespace std;
 4 
 5 
 6 template <class t1,class t2>
 7 t1 ff(t1 a,t1 b,t2 c)
 8 {
 9     cout<<a+b<<' '<<c<<endl;
10     return 0;
11 }
12 
13 int main()
14 {
15     ff(1,2,3.1);
16     ff(1.2,2.0,'a');
17     return 0;
18 }

需要注意的地方有:

1.template关键字表示声明的是模板。

2.<>中时模板的参数表,可以有一项或多项,其中的类型名称为参数化类型,是一种抽象类型或可变类型。

3.class是类型关键字,也可以用typename作为关键字。

4.函数返回值类型可以是普通类型,也可以是模板参数表中指定的类型。

5.模板参数表中的参数类型可以是普通类型。

函数模板定义好后,即可生成各种具体的函数,该过程称之为实例化。函数模板实例化分为显式实例化与隐式实例化。(前面的例子即为隐式实例化)

显式实例化举例:

 1 #include <iostream>
 2 
 3 using namespace std;
 4 
 5 
 6 template <class t1,class t2>
 7 t1 ff(t1 a,t1 b,t2 c)
 8 {
 9     cout<<a+b<<' '<<c<<endl;
10     return 0;
11 }
12 
13 int main()
14 {
15     ff<int,double>(1,2,3.1);
16     ff<double,char>(1.2,2.0,'a');
17     return 0;
18 }

注意一点:当程序里同时出现重载函数和函数模板时,优先绑定重载函数,若是不能精确匹配,方匹配函数模板。

------------------------------------------------------------------------------------------------------------------------------------------------------------------

class A
{
    template <typename T, typename = typename std::enable_if<std::is_integral<typename std::remove_reference<T>::type>::value>::type>
    void f (const std::string& key, T value);
};

template <typename T, typename V>
inline void A::f (const std::string& key, T value)
{
    ///
}

这里是一个项目中用到的例子,T是整数类型,is_integral包含所有整数类型,remove_reference是去引用(如果不这样做,调用方传参带引用,匹配会失败,因为带引用的type与指针类似,不能称之为整数),类外实现带的声明与类内差异很大,V仅仅用作形式上与类内声明保持匹配,没有实际意义。

另外需要注意的是,模板默认内联,必须把实现体放在对应头文件里。

原文地址:https://www.cnblogs.com/jiu0821/p/4156539.html