从字符串文字初始化 char 数组是否被认为是隐式转换?

Is initializing char array from string literal considered to be a implicit conversion?

char x[10] = "banana"; 被认为是从 const char[7]char[10]?

的隐式转换

由于 std::is_convertible<const char[7], char[10]>::value 的计算结果为 false,显而易见的答案是它不是,但我无法在任何地方找到隐式转换的正确定义。阅读 cppreference 我会说这是因为:

Implicit conversions are performed whenever an expression of some type T1 is used in context that does not accept that type, but accepts some other type T2; in particular: ... when initializing a new object of type T2, including return statement in a function returning T2;

虽然我不确定他们为什么不从这种情况中排除显式构造函数。

后续问题(可能没用):

数组是否完全排除在任何类型的转换之外(即数组到数组的转换)?

我没有最新标准的副本,但在 [dcl.init.string] 中,有一段:

If there are fewer initializers than there are array elements, each element not explicitly initialized shall be zero-initialized (8.5).
C++.2011§8.5.2¶3

因此,这是使用文字初始化 char 已知大小数组的指定行为。

在此声明中

char x[10] = "banana";

没有转换。字符串文字的元素用于初始化数组的元素。实际上相当于

char x[10] = { 'b', 'a', 'n', 'a', 'n', 'a', '[=11=]' };

如果你声明的不是数组,而是像

这样的指针
const char *x = "banana";

那么 const char[7] 类型的字符串文字将被隐式转换为指向其第一个 const char *.

类型元素的指针

以上声明等同于

const char *x = &"banana"[0];

从语言法律上讲,从字符串字面量初始化 char 数组是一种隐式转换。

[conv.general]:

An expression E can be implicitly converted to a type T if and only if the declaration T t=<i>E</i>; is well-formed, for some invented temporary variable t ([dcl.init]).

请注意,核心语言只定义了从表达式到类型的隐式转换。所以“从const char[7]char[10]的隐式转换”的含义是不确定的。

只要 To 是数组类型,

is_convertible<From, To>::value 就是 false,因为如果 To 不是有效的 [=,它被定义为生成 false 39=] 类型,数组不是。 (这可以通过不同的方式实现。)

[meta.rel]/5:

The predicate condition for a template specialization is_­convertible<From, To> shall be satisfied if and only if the return expression in the following code would be well-formed, including any implicit conversions to the return type of the function:

To test() {
  return declval<From>();
}

数组很少是隐式转换的目标,因为它们既不是参数类型也不是 return 类型。但他们不排除在temporary materialization conversion.

之外

出于重载决议的目的, 被视为隐式转换,但不涉及实际转换(恒等式转换序列)。参见 [over.ics.list]/4:

Otherwise, if the parameter type is a character array125 and the initializer list has a single element that is an appropriately-typed string-literal (9.4.2), the implicit conversion sequence is the identity conversion.

125 Since there are no parameters of array type, this will only occur as the referenced type of a reference parameter.

隐式转换为数组类型本身(不是对数组的引用)似乎非常受限:它显然只允许在变量定义中使用。 static_cast<char[10]>("banana") 之类的东西不会编译(至少在 GCC 和 Clang 上)。