作用
手册解释如链接。
源码
template <typename T>
class remove_reference
{
public:
typedef T type;
};
template<typename T>
class remove_reference<T&>
{
public:
typedef T type;
};
看看remove_reference 做了什么?
他封装了一个普通的模板类,并且typedef T type,主要看第二个,封装了一个引用类型的T& 。 我们使用时remove_reference<decltype(*a)> ,就会被传到第二个实现中。 remove_reference<int &> ,那么typedef int type ,此时type就会变为int,解除引用。
总结:如果模板T被解释为引用类型,就解引用。
反例一:在不考虑解引用的情况下。
代码
#include "head.h"
#define MY namespace my{
#define MYEND }
using namespace std;
MY
template <typename T>
void swap(T&& a,T&& b){
cout << a << " "<<b<<endl;
T c = a;
a = b;
b = c;
cout << a << " "<<b<<endl;
return ;
}
MYEND
int main(){
int a = 3,b = 4;
my::swap(a,b);
my::swap(123,234);
return 0;
}
结果
3 4
4 4
123 234
234 123
分析
main函数中调用swap(a,b) 时,模板推到T&& = int& (左值),即T = int& . 此时swap函数中就会变成下面的编译结果:
void swap(int& a,int& b){
cout << a << " "<<b<<endl;
int& c = a;
a = b;
b = c;
cout << a << " "<<b<<endl;
return ;
}
此时c是a的引用,进行传递值的时候,直接将b赋值给了a和c。 这就是为什么产生了3,4经过swap函数变成了4,4。
正例:使用解引用
代码
#include "head.h"
#define MY namespace my{
#define MYEND }
using namespace std;
MY
template <typename T>
void swap(T&& a,T&& b){
remove_reference_t<T> c = a;
cout << a << " "<<b << endl;
c = a;
a = b;
b = c;
cout << a << " "<<b << endl;
return ;
}
MYEND
int main(){
int a = 3,b = 4;
my::swap(a,b);
my::swap(123,234);
return 0;
}
结果
3 4
4 3
123 234
234 123
|