首页 > 代码库 > [014]模板-模板实参推导

[014]模板-模板实参推导

对于函数模板,编译器利用调用中的函数实参来确定其函数模板,从函数实参来确定模板实参的过程就被叫做是模板实参推导。

比如:

 1 #include<iostream> 2 #include<string> 3 using namespace std; 4  5 template <class T> 6 int compare(const T &v1, const T &v2) { 7     if (v1 > v2) { 8         cout << "bigger" <<endl; 9         return 0;10     }11     else {12         cout << "small" <<endl;13         return 1;14     }15 }16 17 template <class T>18 int compare1(T v1,T v2) {19     if (v1 > v2) {20         cout << "compare1::bigger" <<endl;21         return 0;22     }23     else {24         cout << "compare1::small" <<endl;25         return 1;26     }27 }28 29 int main() {30     compare(0, 1);                // 调用compare(const int&, const int&)31     compare(3.14, 2.7);           // 调用compare(const float&, const float&)32     compare(2, 2.7);              // error33 34     system("pause");35     return 0;36 }

在模板实参推导过程中,编译器使用函数调用中的实参类型来寻找模板实参,用这些模板实参生成的函数版本与给定的函数调用最为匹配.

一、模板推导规则

模板实参推导还有以下的规则:

1.如果某个函数的多个形参的类型是同一个模板类型形参,推断出来的函数的这些实参类型要完全匹配

   就像上面例子上的compare(2, 2.7);一样,必须完成匹配。

2.如果模板函数的形参是非引用类型,忽略const。例:

    string s1("a");    const string s2("ab");    compare1(s1, s2);   // 调用compare1(string, string)

3.形参如果是const 引用或者指针,实参可以使非const引用或者指针,编译器会自动转换到const。例:

    string s1("a");    const string s2("ab");    compare(s1, s2);    // 调用compare(const string&, const string&)

4.非引用类型模板形参可以将数组或函数类型的实参转换成数组指针或函数指针。例:

    int a[10], b[11];    compare1(a, b);   // 调用compare1(int*, int*)

5.引用类型模板形参不能将将数组或函数类型的实参转换成数组指针或函数指针,参数推导将出错。例:

    int a[10], b[11];    compare(a, b);   // error

6.可以根据函数指针推断模板实参

7.模板实参推断顺序是从函数返回值开始,从左至右逐一推导

二、实参类型不同的模板推导

在上面的1中,如果某个函数的多个形参的类型是同一个模板类型形参,推断出来的函数的这些实参类型要完全匹配,否则则要出错。

但是,我们可以使用多个类型的参数来实现推导。例:

 1 #include<iostream> 2 #include<string> 3 using namespace std; 4  5 template <typename T, typename B> 6 int compare(const T &v1, const B &v2) { 7     if (v1 > v2) { 8         cout << "bigger" <<endl; 9         return 0;10     }11     else {12         cout << "small" <<endl;13         return 1;14     }15 }16 17 int main() {18     long l = 655555;19     compare(l, 2);        // 调用(const long&, const int&)20 21     system("pause");22     return 0;23 }

 

[014]模板-模板实参推导