It’s said that imitation is the sincerest form of flattery, but blissful ignorance can be an equally heartfelt accolade. When users of a complex system are ignorant of how it works, yet happy with what it does, that says a lot about the design of that system. By this measure, template type deduction in C++ is a tremendous success. Millions of programmers have passed arguments to template functions with completely satisfactory results, even though many of those programmers would be hard-pressed to give more than the haziest description of how the types used by those functions were deduced.
从函数实参来确定模板实参的过程被称作模板实参推断。在模板实参推断的过程中,编译器使用函数调用中的实参类型来寻找模板实参,用这些模板实参生成的函数版本与给定的函数调用最为匹配。
template<typename T>
void f(ParamType param);
有三种ParamType的类型。
ParamType is a pointer or reference 1 type, but not a universal reference.
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 read-only view of x
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&
template<typename T>
void f(T* param); // param is now a pointer
int x = 27; // as before
const int *px = &x; // px is a ptr to a read-only view of x
f(&x); // T is int, param's type is int*
f(px); // T is const int,
// param's type is const int*,
ParamType is a universal reference.
template<typename T>
void f(T&& param); // param is now a universal reference
int x = 27; // as before
const int cx = x; // as before
const int& rx = x; // as before
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 1 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&&
PramType is neither a pointer nor a reference.
template<typename T>
void f(T param); // param is now passed by value
int x = 27; // as before
const int cx = x; // as before
const int& rx = x; // as before
f(x); // T and param are both int
f(cx); // T and param are again both int
f(rx); // T and param are still both int