模板型別的推斷
下面的函式f是個模板函式,typename T。下表是,根據呼叫測的實參,推斷出來的T的型別。
請注意下表的紅字部分, f(T&& t)看起來是右值引用,但其實它會根據實參的型別,來決定T的型別,如果實參是左值,則它是左值,如果實參是右值,則它是右值。
所以可以看出來,T&可以變成const& ,f(T&& t)也可以變成const&。
f(T t) | f(const T t) | f(T& t) | f(const T& t) | f(T&& t) | f(const T&& t) | |
---|---|---|---|---|---|---|
f(1) | f<int> | f<int> | error cannot bind non-const lvalue reference of type ‘int&’ to an rvalue of type ‘int` | f<int> | f<int> | f<int> |
int i = 1; f(i); |
f<int> | f<int> | f<int> | f<int> | f<int&> | error cannot bind rvalue reference of type ‘const int&&’ to lvalue of type ‘int’ |
int& ri = i; f(ri); |
f<int> | f<int> | f<int> | f<int> | f<int&> | cannot bind rvalue reference of type ‘const int&&’ to lvalue of type ‘int’ |
const int ci = 2; f(ci); |
f<int> | f<int> | f<const int> | f<int> | f<const int&> | cannot bind rvalue reference of type ‘const int&&’ to lvalue of type ‘const int’ |
const int& rci = ci; f(rci); |
f<int> | f<int> | f<const int> | f<int> | f<const int&> | cannot bind rvalue reference of type ‘const int&&’ to lvalue of type ‘const int’ |
實驗程式碼
#include <iostream>
template<typename T>
void f1(T t){
t = 99;
}
template<typename T>
void f4(const T t){
//t = 99;
}
template<typename T>
void f2(T& t){
//t = 99;
}
template<typename T>
void f3(const T& t){}
template<typename T>
void f5(T&& t){}
template<typename T>
void f6(const T&& t){}
int main(){
/*
//void f1(T t)
f1(1);//int
int i = 1;
f1(i);//int
int& ri = i;
f1(ri);//int
std::cout << ri << std::endl;
const int ci = 2;
f1(ci);//int
const int& rci = ci;
f1(rci);//int
*/
/*
//void f4(const T t)
f4(1);//int
int i = 1;
f4(i);//int
int& ri = i;
f4(ri);//int
std::cout << ri << std::endl;
const int ci = 2;
f4(ci);//int
const int& rci = ci;
f4(rci);//int
*/
/*
//void f2(T& t)
//f2(1);//error cannot bind non-const lvalue reference of type ‘int&’ to an rvalue of type ‘int’
int i = 1;
f2(i);//int
int& ri = i;
f2(ri);//int
const int ci = 2;
f2(ci);//const int
const int& rci = ci;
f2(rci);//const int
*/
/*
//void f3(const T& t)
f3(1);//int
int i = 1;
f3(i);//int
int& ri = i;
f3(ri);//int
const int ci = 2;
f3(ci);//int
const int& rci = ci;
f3(rci);//int
*/
/*
//void f5(T&& t)
f5(1);//int
int i = 1;
f5(i);//int&
int& ri = i;
f5(ri);//int&
std::cout << ri << std::endl;
const int ci = 2;
f5(ci);//const int&
const int& rci = ci;
f5(rci);//const int&
*/
/*
//void f6(const T&& t)
f6(1);//int
int i = 1;
//f6(i);//error cannot bind rvalue reference of type ‘const int&&’ to lvalue of type ‘int’
int& ri = i;
//f6(ri);//error cannot bind rvalue reference of type ‘const int&&’ to lvalue of type ‘int’
std::cout << ri << std::endl;
const int ci = 2;
//f6(ci);//error cannot bind rvalue reference of type ‘const int&&’ to lvalue of type ‘const int’
const int& rci = ci;
//f6(rci);//error cannot bind rvalue reference of type ‘const int&&’ to lvalue of type ‘const int’
*/
}