模板類型基本形如以下:
template<typename T>
void f(ParamType param);
調用類似於下:
f(expr); // call f with some expression
類型推導分以下三種情況:
- 當ParamType是引用或者指針,不是右值引用時
a)如果表達式是引用,那麼忽略引用部分
例如:
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&
template<typename T>
void f(const T& param); // param is now a ref-to-const
int x = 27; // as before
const int cx = x; // as before
const int& rx = x; // as before
f(x); // T is int, param's type is const int&
f(cx); // T is int, param's type is const int&
f(rx); // T is 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 x as a const int
f(&x); // T is int, param's type is int*
f(px); // T is const int,
// param's type is const int*
- 當ParamType是右值引用時
a)如果表達式是左值,那麼T和ParamType都被推導爲左值引用
b)如果表達式是右值,那麼可按1規則推導
例如:
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 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&&
- 當ParamType既不是指針也不是引用時
a)如果表達式是引用,那麼忽略引用
b)除引用外,如果還有const,volatile,那麼一樣都忽略。
例如:
int x = 27; // as before
const int cx = x; // as before
const int& rx = x; // as before
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
.
c)如果是指針,則推導爲指針的類型
d)如果是數組,則推導爲指針的類型
e)如果爲函數類型
如:
void someFunc(int, double); // someFunc is a function;
// type is void(int, double)
template<typename T>
void f1(T param); // in f1, param passed by value
template<typename T>
void f2(T& param); // in f2, param passed by ref
f1(someFunc); // param deduced as ptr-to-func;
// type is void (*)(int, double)
f2(someFunc); // param deduced as ref-to-func;
// type is void (&)(int, double)