为什么const char []上的类型推导与const char *不同?

问题描述

在第一个调用中,当我将char const []传递给参数为T const a的模板函数时,将T推导为char const *,这是合理的,因为{{ 1}}是指衰减指针。

但是,当参数类型更改为const时,T const & a被推导为T。从上面的观点来看,char[7]为什么不限定整个数组类型?

const

解决方法

const为什么不限定整个数组类型

因为array type

(重点是我的)

cv-qualifiers应用于数组类型(通过typedef或模板类型操作)会将限定符应用于元素类型,但是会考虑其元素为cv限定类型的任何数组类型具有相同的简历资格。

// a and b have the same const-qualified type "array of 5 const char"
typedef const char CC;
CC a[5] = {}; 
typedef char CA[5];
const CA b = {};

这意味着当Tchar[7] T const导致类型为char const[7]时,则T const&(即a的类型)为char const (&)[7]

另一方面,当您传递类型为s的数组const char[7]时,该数组也被视为const限定的。因此,在给定参数类型T const&的情况下,可以将T推导出为char[7](而不是char const[7])。

,

这是因为数组在C ++中是不可复制且不可分配的。

因此,在调用show1时,const char[]类型会衰减为const char*。该语言允许在函数调用站点上对每个参数进行一次隐式转换。

使用show2时,您通过引用传递-无需复制或分配,因此不会发生指针衰减。

,
template <typename T>
void show(ParameterType a) {
}

show(expression);

编译器使用expression来推断TParameterType。如果T包含ParameterType之类的限定词,则ParameterTypeconst是不同的。

如果ParameterType既不是指针也不是引用(show1的情况,T const),则T的类型是expression的类型,没有const,{ {1}}和参考。因此volatileT的类型。 const char *ParameterType的类型)为a

如果const char * const(show2中的ParameterType)是指针或引用(但不像T const &这样引用)。首先忽略引用,该引用给出结果T&&(与T const相同)。 const Texpression)与const char []的第二个匹配类型,因此const TT

有关更多信息,Item 1 of Effective Modern C++ by Scott Meyers正是您想要的。规则比我在这里描述的要复杂,但非常重要。