标签:style blog http io color ar os sp strong
一、什么是实参演绎
1 template<typename T> 2 T const& max(T const& a T const& b) 3 { 4 return a < b ? b : a; 5 } 6 7 int g = max(1, 1.0);
1 template<typename T> 2 typename T::ElementT at(T const& a, int i) 3 { 4 return a[i]; 5 } 6 7 void f(int* p) 8 { 9 int g = at(p, 1);// 这里会演绎失败,因为T被演绎成T*,但是int*没有一个叫做ElementT的替换类型。 10 }
template<typename T> void f(T); //P是 T template<typename T>void g(T&); //P是T double x[20]; int const seven = 7; f(x); //T被演绎成double*,decay转化 g(x);//T被演绎成double[20] f(seven);//T被演绎成int,忽略了高层的const g(seven);//T被演绎成int const,不会忽略 f(7);//T被演绎成int g(7);//T被演绎成int,但是7不能传递给int&
(5)又一个坑:实参为字符串,那么演绎的结果T应该是字符串数组,不是字符串指针char*
template<typename T> T const& max(T const& a, T const& b);
max("Apple", "Pear");“Apple”的类型是char const[6], “Pear”的类型是char const[5];而且不存在数组到指针的decay转型(因为演绎的参数是引用参数)。因此为了演绎成功,T就同时必须得是char[6]和char[5]。这显然是不可能的,所以产生错误。
三、练手
template<typename T> void f1(T*); template<typename E, int N> void f2(E(&)[N]); template<typename T1, typename T2, typename T3> void f3(T1(T2::*)(T3*)); class S{ public: void f(double*); }; void g(int ***ppp) { bool b[42]; f1(ppp); //演绎T为int*** f2(b); //演绎E为bool, N为42 f3(&S::f); //演绎T1为void, T2为S,T3为double }
template<int N> class X{ public: typedef int I; void f(int){} };
现在如果用 一个int 演绎typename X<N>::I ,那么是不成功的,为什么因为我可以有很多X<1>::i,X<2>::I, X<3>::I …… X<1000>::I,表示,所以C++禁止这种演绎。
template<int N> void fppm(void (X<N>::*p)(typename X<N>::I)); int main() { fppm(&X<33>::f);//可以演绎成功,N=33 }
template<typename T> void f(T, T); void (*pf)(char, char) = &f;
class S{ public: template<typename T, int N> operator T[N]&(); //我是转型运算符,转换成T[N]类型 }; void f(int(&)[20]); //参数的类型是20个元的数组 void g(S s) { f(s); }
template<typename T> class B{}; template<typename T> class D:public B<T>{ }; template<typename T> void f(B<T>*); void g(D<long> dl) { f(&dl); //成功,用long替换T }
template<typename T> void f(T x = 42) {} int main() { f<int>(); //正确,实例化 f();//错误,不能用于实参演绎 }
#include <iostream> using namespace std; template<typename T> class Object{ public: int a; Object(int n):a(n){} friend bool operator == (Object<T> const<, Object<T> const& rt) { return equal(lt, rt); //根据参数类型调用重载的函数 } }; bool equal(Object<int> const& lt, Object<int> const& rt) //这是一个普通函数,可以被随便重载 { return lt.a == rt.a; } int main() { Object<int> s(1); Object<int> s1(1); cout << (s == s1) << endl; return 0; }
最后顺利编译通过,运行成功。
标签:style blog http io color ar os sp strong
原文地址:http://www.cnblogs.com/claruarius/p/4084942.html