模板型別扣除
模板通用語法
template<typename T>
void f(ParamType param);
f(expr);
情況 1:ParamType
是參考或指標,但不是通用或前向參考。在這種情況下,型別推導以這種方式工作。如果參考部分存在於 expr
中,編譯器將忽略該參考部分。然後編譯器將 expr
的型別與 ParamType
進行模式匹配,以確定 T
。
template<typename T>
void f(T& param); //param is a reference
int x = 27; // x is an int
const int cx = x; // cx is a const int
const int& rx = x; // rx is a reference to x as a const int
f(x); // T is int, param's type is int&
f(cx); // T is const int, param's type is const int&
f(rx); // T is const int, param's type is const int&
案例 2:ParamType
是通用參考或前向參考。在這種情況下,如果 expr
是 rvalue,則型別推導與情況 1 相同。如果 expr
是左值,T
和 ParamType
都推導為左值參考。
template<typename T>
void f(T&& param); // param is a universal reference
int x = 27; // x is an int
const int cx = x; // cx is a const int
const int& rx = x; // rx is a reference to x as a const int
f(x); // x is lvalue, so T is int&, param's type is also int&
f(cx); // cx is lvalue, so T is const int&, param's type is also const int&
f(rx); // rx is lvalue, so T is const int&, param's type is also const int&
f(27); // 27 is rvalue, so T is int, param's type is therefore int&&
案例 3:ParamType
既不是指標也不是參考。如果 expr
是參考,則忽略參考零件。如果 expr
也是 const,也會被忽略。如果它是 volatile,則在推導 T 的型別時也會被忽略。
template<typename T>
void f(T param); // param is now passed by value
int x = 27; // x is an int
const int cx = x; // cx is a const int
const int& rx = x; // rx is a reference to x as a const int
f(x); // T's and param's types are both int
f(cx); // T's and param's types are again both int
f(rx); // T's and param's types are still both int