函数模版中的引用

来源:互联网 发布:社交媒体数据可视化 编辑:程序博客网 时间:2024/06/09 14:59

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

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


    原创粉丝点击
    热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 老是恶心想吐是怎么回事 老是头疼恶心想吐怎么回事 老是恶心想吐怎么回事 胃胀恶心想吐怎么回事 突然头疼恶心想吐是怎么回事 犯恶心想吐是怎么回事 天天恶心想吐怎么回事 恶心想吐拉肚子怎么回事 头晕耳鸣恶心想吐是怎么回事 头疼恶心吐怎么回事 恶心想吐拉肚子 咳嗽恶心想吐怎么回事 偏头疼恶心想吐是怎么回事 经常头疼恶心想吐是怎么回事 突然头痛恶心想吐是怎么回事 胃胀痛恶心是怎么回事 头痛 恶心 想吐 老是恶心是怎么回事 头疼加恶心是怎么回事 头晕头疼恶心想吐是怎么回事 头疼头晕恶心想吐是怎么回事 胃难受恶心想吐怎么回事 经常头晕恶心想吐是怎么回事 孕妇头晕恶心想吐是怎么回事 突然恶心想吐是怎么回事 恶心吐怎么回事 恶心想吐头晕 胃部不舒服恶心想吐 晚上恶心想吐是怎么回事 总恶心是怎么回事 恶心想吐头晕怎么回事 胃难受恶心怎么回事 来月经恶心想吐怎么回事 胃老是恶心怎么回事 老是头疼恶心怎么回事 为什么恶心想吐 经期恶心想吐是怎么回事 老是恶心想吐 头疼还恶心想吐咋回事 胃痛有点恶心想吐 感冒头晕恶心想吐是怎么回事