函数模版中的引用

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

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)


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值