模板类型扣除

模板通用语法

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 是左值,TParamType 都推导为左值参考。

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