#include "stdafx.h" #include<iostream> #include<ostream> #include<istream> template<class T> int compare( T ls, T rs) { if(ls<rs) return -1; if(rs<ls) return 1; return 0; } template<> int compare(const int& ls,const int& rs) { std::cout<<"first \n"; if(ls<rs) return -1; if(rs<ls) return 1; return 0; } int _tmain(int argc, _TCHAR* argv[]) { int first1(1),first2(2); int &second1(first1); int &second2(first2); const int &third1(first1); const int &third2(first2); int r(0); r = compare(first1,first2); std::cout<<r<<'\n'; r = compare(second1,second2); std::cout<<r<<'\n'; r = compare(third1,third2); std::cout<<r<<'\n'; r = compare(3,2); std::cout<<r<<'\n'; std::cin>>r; return 0; }
对compare模版定义了 const &int的特化,请预测结果是:
?
实际上结果是
-1
-1
-1
1
也就是四个调用都实例了函数模版,并没有调用特化模版,甚至常量引用third1,third2作为参数仍然么有调用对应的特化模版。
如果我们去掉特化模版形参的const和&如下:
#include "stdafx.h" #include<iostream> #include<ostream> #include<istream> template<class T> int compare( T ls, T rs) { if(ls<rs) return -1; if(rs<ls) return 1; return 0; } template<> int compare( int ls, int rs) { std::cout<<"first \n"; if(ls<rs) return -1; if(rs<ls) return 1; return 0; } int _tmain(int argc, _TCHAR* argv[]) { int first1(1),first2(2); int &second1(first1); int &second2(first2); const int &third1(first1); const int &third2(first2); int r(0); r = compare(first1,first2); std::cout<<r<<'\n'; r = compare(second1,second2); std::cout<<r<<'\n'; r = compare(third1,third2); std::cout<<r<<'\n'; r = compare(3,2); std::cout<<r<<'\n'; std::cin>>r; return 0; }结果为
first
-1
first
-1
first
-1
first
1
全部调用特化函数模版。
当特化模版形参为引用时,如下
#include "stdafx.h" #include<iostream> #include<ostream> #include<istream> template<class T> int compare( T ls, T rs) { if(ls<rs) return -1; if(rs<ls) return 1; return 0; } template<> int compare( int &ls, int &rs) { std::cout<<"first \n"; if(ls<rs) return -1; if(rs<ls) return 1; return 0; } int _tmain(int argc, _TCHAR* argv[]) { int first1(1),first2(2); int &second1(first1); int &second2(first2); const int &third1(first1); const int &third2(first2); int r(0); r = compare(first1,first2); std::cout<<r<<'\n'; r = compare(second1,second2); std::cout<<r<<'\n'; r = compare(third1,third2); std::cout<<r<<'\n'; r = compare(3,2); std::cout<<r<<'\n'; std::cin>>r; return 0; }结果是
-1
-1
-1
1
这次所有都调用的是实例化的函数模版而不是特化函数模版。接下来对函数模版compare添加引用
#include "stdafx.h" #include<iostream> #include<ostream> #include<istream> template<class T> int compare( T &ls, T &rs) { if(ls<rs) return -1; if(rs<ls) return 1; return 0; } template<> int compare(const int& ls,const int& rs) { std::cout<<"first \n"; if(ls<rs) return -1; if(rs<ls) return 1; return 0; } int _tmain(int argc, _TCHAR* argv[]) { int first1(1),first2(2); int &second1(first1); int &second2(first2); const int &third1(first1); const int &third2(first2); int r(0); r = compare(first1,first2); std::cout<<r<<'\n'; r = compare(second1,second2); std::cout<<r<<'\n'; r = compare(third1,third2); std::cout<<r<<'\n'; r = compare(3,2); std::cout<<r<<'\n'; std::cin>>r; return 0; }
r = compare(3,2);
时提示
1>e:\sourcecodes\comparetest\comparetest\comparetest.cpp(67) : error C2664: 'compare' : cannot convert parameter 1 from 'int' to 'int &'这个错误和
int &a = 1;
以下转自http://developer.51cto.com/art/201002/183476.htm
关于引用的初始化有两点值得注意:
(1)当初始化值是一个左值(可以取得地址)时,没有任何问题;
(2)当初始化值不是一个左值时,则只能对一个const T&(常量引用)赋值。而且这个赋值是有一个过程的:
首先将值隐式转换到类型T,然后将这个转换结果存放在一个临时对象里,最后用这个临时对象来初始化这个引用变量。
- double temp = double(1);
- const double& cdr = temp;
注释掉语句
r = compare(3,2); std::cout<<r<<'\n';所得结果为
-1
-1
-1
所以我们再次将函数模版compare的形参加上const
#include "stdafx.h" #include<iostream> #include<ostream> #include<istream> template<class T> int compare( const T &ls, const T &rs) { if(ls<rs) return -1; if(rs<ls) return 1; return 0; } template<> int compare(const int& ls,const int& rs) { std::cout<<"first \n"; if(ls<rs) return -1; if(rs<ls) return 1; return 0; } int _tmain(int argc, _TCHAR* argv[]) { int first1(1),first2(2); int &second1(first1); int &second2(first2); const int &third1(first1); const int &third2(first2); int r(0); r = compare(first1,first2); std::cout<<r<<'\n'; r = compare(second1,second2); std::cout<<r<<'\n'; r = compare(third1,third2); std::cout<<r<<'\n'; r = compare(3,2); std::cout<<r<<'\n'; std::cin>>r; return 0; }
first
-1
first
-1
first
-1
first
1
这次均调用了特化的函数模版!!!!
接下来我们在特化模版后再加入同样形参的函数
int compare(const int& ls,const int& rs)如下
#include "stdafx.h" #include<iostream> #include<ostream> #include<istream> template<class T> int compare( const T &ls, const T &rs) { if(ls<rs) return -1; if(rs<ls) return 1; return 0; } template<> int compare(const int& ls,const int& rs) { std::cout<<"first \n"; if(ls<rs) return -1; if(rs<ls) return 1; return 0; } int compare(const int& ls,const int& rs) { std::cout<<"SECOND \n"; if(ls<rs) return -1; if(rs<ls) return 1; return 0; } int _tmain(int argc, _TCHAR* argv[]) { int first1(1),first2(2); int &second1(first1); int &second2(first2); const int &third1(first1); const int &third2(first2); int r(0); r = compare(first1,first2); std::cout<<r<<'\n'; r = compare(second1,second2); std::cout<<r<<'\n'; r = compare(third1,third2); std::cout<<r<<'\n'; r = compare(3,2); std::cout<<r<<'\n'; std::cin>>r; return 0; }这次结果为
SECOND
-1
SECOND
-1
SECOND
-1
SECOND1
从结果我们可以看出函数重载了函数模版以及特化模版。
#include "stdafx.h" #include<iostream> #include<ostream> #include<istream> template<class T> int compare( T ls, T rs) { if(ls<rs) return -1; if(rs<ls) return 1; return 0; } int compare(const int& ls,const int& rs) { std::cout<<"SECOND \n"; if(ls<rs) return -1; if(rs<ls) return 1; return 0; }
SECOND
-1
SECOND
-1
SECOND
-1
SECOND
1
重载函数去掉const,只留&
#include "stdafx.h" #include<iostream> #include<ostream> #include<istream> template<class T> int compare( T ls, T rs) { if(ls<rs) return -1; if(rs<ls) return 1; return 0; } int compare( int& ls, int& rs) { std::cout<<"SECOND \n"; if(ls<rs) return -1; if(rs<ls) return 1; return 0; }
SECOND
-1
SECOND
-1
-1
1
说明int,int &调用的函数,const &,常量数字调用的函数模版。
#include "stdafx.h" #include<iostream> #include<ostream> #include<istream> template<class T> int compare( T ls, T rs) { if(ls<rs) return -1; if(rs<ls) return 1; return 0; } int compare( int ls, int rs) { std::cout<<"SECOND \n"; if(ls<rs) return -1; if(rs<ls) return 1; return 0; }
SECOND
-1
SECOND
-1
SECOND
-1
SECOND
1
均调用的函数非模版。
为模版添加引用
#include "stdafx.h" #include<iostream> #include<ostream> #include<istream> template<class T> int compare( T &ls, T &rs) { if(ls<rs) return -1; if(rs<ls) return 1; return 0; } int compare( int ls, int rs) { std::cout<<"SECOND \n"; if(ls<rs) return -1; if(rs<ls) return 1; return 0; }
SECOND
-1
SECOND
-1
SECOND
-1
SECOND
1
再添加常量
#include "stdafx.h" #include<iostream> #include<ostream> #include<istream> template<class T> int compare( const T &ls, const T &rs) { if(ls<rs) return -1; if(rs<ls) return 1; return 0; } int compare( int ls, int rs) { std::cout<<"SECOND \n"; if(ls<rs) return -1; if(rs<ls) return 1; return 0; }
SECOND
-1
SECOND
-1
SECOND
-1
SECOND
1
#include "stdafx.h" #include<iostream> #include<ostream> #include<istream> template<class T> int compare( T &ls, T &rs) { if(ls<rs) return -1; if(rs<ls) return 1; return 0; } int compare( int &ls, int &rs) { std::cout<<"SECOND \n"; if(ls<rs) return -1; if(rs<ls) return 1; return 0; }结果
SECOND
-1
SECOND
-1
r = compare(3,2);出错
1>e:\sourcecodes\comparetest\comparetest\comparetest.cpp(78) : error C2665: 'compare' : none of the 2 overloads could convert all the argument types 1> e:\sourcecodes\comparetest\comparetest\comparetest.cpp(9): could be 'int compare<int>(T &,T &)' 1> e:\sourcecodes\comparetest\comparetest\comparetest.cpp(33): or 'int compare(int &,int &)'
#include "stdafx.h" #include<iostream> #include<ostream> #include<istream> template<class T> int compare( T ls, T rs) { if(ls<rs) return -1; if(rs<ls) return 1; return 0; } int compare( int &ls, int &rs) { std::cout<<"SECOND \n"; if(ls<rs) return -1; if(rs<ls) return 1; return 0; }
SECOND
-1
SECOND
-1
-1
最后留下的疑问是当函数模版的参数不是引用时,如下,
int compare( T ls, T rs)为什么特化模版
template<> int compare(const int& ls,const int& rs)没有起到作用
而
template<> int compare( int ls, int rs)