连接两个字符串文字 我正在读凯尼格加速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;