连接两个字符串文字 我正在读凯尼格加速C++。他写道,“新的想法是,我们可以使用+连接一个字符串和一个字符串文本,或者,就这一点而言,连接两个字符串(但不是两个字符串文本)

连接两个字符串文字 我正在读凯尼格加速C++。他写道,“新的想法是,我们可以使用+连接一个字符串和一个字符串文本,或者,就这一点而言,连接两个字符串(但不是两个字符串文本),c++,string,syntax,operators,concatenation,C++,String,Syntax,Operators,Concatenation,好吧,我想这是有道理的。现在来看两个单独的练习,旨在阐明这一点 下列定义有效吗 const string hello = "Hello"; const string message = hello + ",world" + "!"; 现在,我试着执行上面的操作,它成功了!所以我很高兴 然后我试着做下一个练习 const string exclam = "!"; const string message = "Hello" + ",world" + exclam; 这不起作用。现在我明白这

好吧,我想这是有道理的。现在来看两个单独的练习,旨在阐明这一点

下列定义有效吗

const string hello = "Hello";

const string message = hello + ",world" + "!";
现在,我试着执行上面的操作,它成功了!所以我很高兴

然后我试着做下一个练习

const string exclam = "!";

const string message = "Hello" + ",world" + exclam;

这不起作用。现在我明白这与不能连接两个字符串文字有关,但我不明白为什么我成功地让第一个示例起作用(不是“,”world“和“!”两个字符串文字?这不应该起作用吗?)但不是第二个。

字符串(或者准确地说,
std::string
)和字符文本之间的区别在于后者没有定义
+
运算符。这就是第二个示例失败的原因

在第一种情况下,编译器可以找到合适的
运算符+
,第一个参数是
字符串
,第二个参数是字符文本(
const char*
),因此它使用了该参数。该操作的结果再次是
字符串
,因此它在添加
时重复相同的技巧!“
将其删除

const string message = "Hello" + ",world" + exclam;
+
运算符具有从左到右的关联性,因此等效的括号表达式为:

const string message = (("Hello" + ",world") + exclam);
如您所见,两个字符串文本
“Hello”
“world”
首先被“添加”,因此出现了错误

连接的前两个字符串之一必须是
std::string
对象:

const string message = string("Hello") + ",world" + exclam;
或者,可以通过将表达式的该部分插入括号,强制首先计算第二个
+

const string message = "Hello" + (",world" + exclam);
您的第一个示例(
hello+”,world“+”!“
)之所以有效,是因为
std::string
hello
)是最左边的
+
的参数之一。计算
+
,结果是带有连接字符串的
std::string
对象,然后将得到的
std::string
”连接起来!“


至于为什么不能使用
+
连接两个字符串文字,这是因为字符串文字只是一个字符数组(一个
常量字符[N]
,其中
N
是字符串的长度加上一,对于空终止符)。在大多数上下文中使用数组时,它会转换为指向其初始元素的指针

因此,当您尝试执行
“Hello”+“,world”
,您真正尝试的是将两个
常量char*
添加在一起,这是不可能的(将两个指针添加在一起意味着什么?),如果是,它将不会执行您希望它执行的操作


请注意,您可以通过将字符串文字彼此相邻来连接它们;例如,以下两种文字是等效的:

"Hello" ",world"
"Hello,world"

如果要将一个长字符串文本拆分为多行,则此选项非常有用。但它们必须是字符串文本:这不适用于
const char*
指针或
const char[N]
数组。

您的第二个示例不起作用,因为两个字符串文本没有
运算符+
。请注意,字符串文本不是
string
类型,而是
const char*
类型。如果您这样修改它,您的第二个示例将起作用:

const string message = string("Hello") + ",world" + exclam;

在案例1中,由于操作顺序,您得到:

(你好+”,世界“+”!“解析为hello+”!“最后向你问好

在案例2中,正如James所指出的,您可以得到:

(“Hello”+,world”)+感叹号,它是两个字符串文本的concat


希望清楚:)

您应该始终注意类型

尽管它们看起来都像字符串,
“Hello”
“,world”
都是文本

在您的示例中,
exporm
是一个
std::string
对象

C++有一个运算符重载,它接受一个
std::string
对象并向其添加另一个字符串。当您将
std::string
对象与一个文本连接时,它将对该文本进行适当的转换


但是如果您尝试连接两个文本,编译器将无法找到接受两个文本的运算符。

因为C++14可以使用两个实数:


另外,
const-string-message=“Hello”+(“,world”+感叹号);
也可以工作,因为显式括号(这是一个单词吗?)。如果您指出第一个示例工作的原因,可能会更完整:
const-string-message=((Hello+“,world”)+“!”);
谢谢!我怀疑它与从左到右的关联性有关,但我不确定,这种语义差异对我来说没有多大意义。我很感激你的回答!我要提到的是
“Hello”,“world”
语法不仅对打断多行很有用,而且在其中一个字符串文字是宏时也很有用(或者两者都有)。然后在编译时发生连接。
const string message=“Hello”,“world”+感叹词(例如,省略第一个
+
)应该很好。@Joe-如果你能做到
“Hello”+“,world!”
,为什么有人会写
“Hello”+“,world!”
!“通常,C++有一个令人敬畏的简单的解决问题的方法。”-“我想,如果你使用一个定义(乔),即使是这样,你也更可能写代码<你好”,“World!”<代码>(没有<代码> +<代码>)。有很多关于C++的抱怨,但我认为这里的处理不是一个。这和你写的
1/3+1.5
完全一样,因为除法是整数除法而抱怨。不管是好是坏,大多数语言都是这样
const string hello = "Hello"s;

const string message = hello + ",world"s + "!"s;
const string exclam = "!"s;

const string message = "Hello"s + ",world"s + exclam;