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

7
在第一次调用时,当我将 char const [] 传递给具有参数 T const a 的模板函数时,T 推断为 char const *,这是合理的,因为 const指的是衰减指针。
然而,当参数类型更改为 T const & a 时,T 推断为 char[7]。从上面的角度来看,为什么 const 没有修饰整个数组类型呢?
template <typename T>
void show1(T const a) {
     // input is const char *
     // T is char const *
     // a is char const * const
}

template <typename T>
void show2(T const & a) {
     // input is char const [7]
     // T is char[7]
     // a is char const (&)[7]
}

int main() {
    const char s[] = "asdasd";
    show1(s);
    show2(s);
}
3个回答

4

为什么 const 不修饰整个数组类型

因为对于数组类型

(强调是我的)

Applying cv-qualifiers to an array type (through typedef or template type manipulation) applies the qualifiers to the element type, but any array type whose elements are of cv-qualified type is considered to have the same cv-qualification.

// 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]
另一方面,当您传递具有类型 const char[7] 的数组 s 时,该数组也被视为带有 const 限定符。因此,给定参数类型 T const&T 推断为 char[7](但不是 char const[7])。

感谢您的关注,第二句话似乎与此无关。 - BAKE ZQ
@BAKEZQ 我认为这是相关的,只是方向相反,当元素被const限定时,数组被视为const限定 - songyuanyao
根据第二句话,如果推断是这样的?1:char const [7] 被视为 const(char[7])。2:由于参数类型是 T const &,因此 T 被推断为 char[7] - BAKE ZQ
@BAKEZQ 是的,没错。 - songyuanyao

1
这是因为在C++中,数组是不可复制和不可赋值的。
因此,在调用show1时,const char[]类型会衰减为const char*。语言允许在函数调用站点每个参数进行一次隐式转换。
使用show2时,您正在通过引用传递-不需要复制或分配,因此指针衰减不会发生。

为什么第二种情况中的const不像char const [7] const一样,不能使char const [7]符合条件? - BAKE ZQ

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

show(expression);

编译器使用表达式来推断TParameterType。如果ParameterType包含像const这样的限定符,则TParameterType是不同的。

如果ParameterType既不是指针也不是引用(例如您的show1中的情况,T const),则T的类型是没有constvolatile和引用的expression的类型。因此,T的类型是const char *ParameterTypea的类型)是const char * const

如果ParameterType(在您的show2中为T const &)是指针或引用(但不是像T&&这样的引用)。首先忽略引用,这会得到结果T const(与const T相同)。其次,将expression的类型(const char [])与const T匹配,因此Tchar []

想要了解更多信息,《Effective Modern C++》第一章 by Scott Meyers正是您所需要的。规则比我在这里描述的要复杂得多,但非常重要。


我也是这样想的,按照这个规则,T constconst 应该修饰整个数组类型,即 char const []。从普通的角度来看,const char [] 中的 const 修饰了类型 char,就像第一段代码一样,所以导致了我的困惑。被接受的答案中的引用似乎可以解释这个问题。 - BAKE ZQ

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接