函数模版中的引用

一:函数模版和特化模版的引用

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(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

这次所有都调用的是实例化的函数模版而不是特化函数模版。

2.函数模版的参数变化

接下来对函数模版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,然后将这个转换结果存放在一个临时对象里,最后用这个临时对象来初始化这个引用变量。

  • const double& cdr = 1; // ok
  • 相当于

      
      
      
      
    1. double temp = double(1);  
    2. 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

    这次均调用了特化的函数模版!!!!

    3.加上重载函数

    接下来我们在特化模版后再加入同样形参的函数

    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

    从结果我们可以看出函数重载了函数模版以及特化模版。


    4重载和函数模版

    #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)


    你可能感兴趣的:(c,2010,Types)