在第一个情况中,字符串字面量会衰减为指向
const char的指针。尽管
s1
应该是
const char *
,但一些编译器允许将其作为扩展形式。
const char* s1 = "hello world" ;
一个字符串字面量是一个
由const char
组成的数组,我们可以从
draft C++ standard第
2.14.5
节
String literals中看到这一点,该节说道(
接下来强调我的重点):
普通字符串字面量和UTF-8字符串字面量也称为窄字符串字面量。 窄字符串字面量具有类型“n const char
的数组”,其中n是下面定义的字符串的大小,并具有静态存储期(3.7)。
数组到指针的转换在第4.2
节Array-to-pointer conversion中介绍,该节说:
[...] 具有类型“类型的数组”的表达式被转换为具有类型“指向数组对象的初始元素的指针”的表达式,并且不是lvalue。[...]
您的其他案例无法工作,因为标量只能用花括号内的单个元素进行初始化,这可以是算术类型、枚举类型或指针类型。这在C++标准草案第8.5.1节中有所涵盖,其中第3段提到:
“对象或类型T的引用的列表初始化定义如下:”
然后列举了不同的情况,适用于此情况的右侧的唯一情况是以下符号:
“否则,如果初始化程序列表具有E类型的单个元素,并且T不是引用类型或其引用类型与E相关,则对象或引用从该元素初始化; 如果需要缩小转换(见下文)将元素转换为T,则程序是非法的。”
这要求列表只有一个元素,否则将应用最终的符号:
“否则,程序是非法的。”
在您的两种情况下,即使将初始化器减少为一个变量,类型也是不正确的。h是一个char,2是int,无法转换为指针。
可以通过将结果分配给数组来使赋值工作,例如以下方式:
char s1[] = { 'h', 'e', 'l', 'l', 'o',' ', 'w', 'o', 'r', 'l', 'd' } ;
int a[] = { 2, 3, 1, 45, 6 } ;
这将在第
8.5.1
部分
集合 中涉及,其内容如下:
An array of unknown size initialized with a brace-enclosed
initializer-list containing n initializer-clauses, where n shall be
greater than zero, is defined as having n elements (8.3.4). [ Example:
int x[] = { 1, 3, 5 };
declares and initializes x as a one-dimensional array that has three
elements since no size was specified and there are three initializers.
—end example ] An empty initializer list {} shall not be used as the
initializer-clause for an array of unknown bound.104
注意:
说指针不能使用花括号初始化列表是不正确的,它可以完全用于指针:
int x = 10 ;
int *ip = &x ;
int *a = {nullptr} ;
int *b = {ip} ;
".."
这个东西。理论上,我认为你也可以将其用于其他类型的初始化(类似于 C99 复合字面量)。 - dyp{..}
不是一个对象,甚至不是一个表达式,也没有类型。它是一个 花括号初始化列表。 - dypconst
**char *s1 = "hello world";
代替。 - Ben Voigt