标准库允许把字符串字面值和字符字面值转换为 string 对象,当把 string 对象和字符字面值以及字符串字面值混在一条语句中使用时,必须确保加法运算符( + )的两侧运算对象至少有一个是 string:

1
2
3
4
5
6
7
8
string s1 = "hello", s2 = "world";
string s3 = s1 + ", " + s2 + 'n';
string s4 = s1 + ", ";
string s5 = "hello" + ", "; // 错误,两个运算对象都不是 string

// 正确,每个加法运算符都有一个运算对象 string
string s6 = s1 + ", " + "world";
string s7 = "hello" + ", " + s2; // 错误,不能把字面值直接相加

s6 的初始化形式的工作机理和连续输入连续输出相同,可以用如下的形式分组:

1
string s6 = (s1 + ", ") + "world";

其中 s1 + ", " 的结果是一个 string 对象,它同时作为第二个加法运算符的左侧运算对象,因此上述语句和下面的两个语句是等价的:

1
2
string tmp = s1 + ", ";    // 正确,加法运算符有一个运算对象是 string
string s6 = tmp + "world"; // 正确,加法运算符有一个运算对象是 string

另一方面,s7 的初始化是非法的,根据其语义加上括号后就成了下面的形式:

1
string s7 = ("hello" + ", ") + s2;  // 错误,不能把字面值直接相加

很容易看到,括号内的子表达式试图把两个字符串字面值加在一起,而编译器根本没法做到这一点,所以这条语句是错误的。

因为某些历史原因,也为了与 C 兼容,所以 C++ 语言中的字符串字面值并不是标准库类型 string 的对象,切记,字符串字面值与 string 是不同的类型