将指针传递给模板参数时类型推导的规则是什么

What is the rules of type deduction while passing pointer to template argument

我正在学习如何在C++11中使用模板,我刚刚看了一篇关于模板的文章,它向我展示了类型推导的规则并提供了参考。例如,

template<typename T>
void f(const T& param);

int x = 27;
const int cx = x;
const int& rx = x;

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&
f(27); // T is int, param's type is const int&

此外,它还谈到了引用崩溃:

template<typename T>
void f(T&& param);

int x = 27;
const int cx = x;
const int& rx = x;

f(x);   // x is lvalue,  so T is int&,       param's type is int&
f(cx);  // cx is lvalue, so T is const int&, param's type is const int&
f(rx);  // rx is lvalue, so T is const int&, param's type is const int&
f(27);  // 27 is rvalue, so T is int,        param's type is int&&

好吧,现在我明白了所有这些,但现在,我正在考虑指针。这个问题彻底炸裂了我的大脑,但似乎它会变得非常复杂。

例如,假设我们有 int *const int *。现在,如果我们有以下三个模板函数:

template<typename T>
void f(T param);

template<typename T>
void f(T *param);

template<typename T>
void f(const T *param);

template<typename T>
void f(T& param);

template<typename T>
void f(const T& param);

template<typename T>
void f(T&& param);

如果我们传递一个int *,编译器如何进行类型推导? const int * 怎么样?

如您所知,模板中的类型推导分为三个不同的类别,其中模板函数的参数类型是 1) 引用或指针,2) 转发(a.k.a 通用)引用,或最后 3) pointer/reference 或转发引用都不是。

所以,如果你有一个指针,类型推导就像这三种情况一样工作。

对于案例 1-A:

template<typename T>
void f(T* param);

int x = 27;
int* px = &x;
const int* cpx = &x;

f(px);   // T is int and param's type is int *
f(cpx);  // T is const int and param's type is const int *

对于案例 1-B:

template<typename T>
void f(T& param);

int x = 27;
int* px = &x;
const int* cpx = &x;

f(px);   // T is int* and param's type is int*&
f(cpx);  // T is const int* and param's type is const int*&

对于案例 2:

template<typename T>
void f(T&& param);

int x = 27;
int* px = &x;
const int* cpx = &x;

f(px);   // T is int*& and param's type is int*&
f(cpx);  // T is const int*& and param's type is const int*&

对于案例 3:

template<typename T>
void f(T param);

int x = 27;
int* px = &x;
const int* cpx = &x;

f(px);   // T is int * and param's type is int *
f(cpx);  // T is const int * and param's type is const int *