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

问题描述

我正在学习如何在 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,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) 转发(又名通用)引用,或最后 3) 两者都不是指针/参考或转发参考。

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

对于案例 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 *