为什么我可以构造具有多个字符串文本的字符串?

Why can I construct a string with multiple string literals?

本文关键字:字符串 文本 我可以 为什么      更新时间:2023-10-16
#include <iostream>
#include <string>
int main() {
std::string str = "hello " "world" "!";
std::cout << str;
}

以下内容将编译、运行和打印:

世界您好!

观看直播


似乎字符串文字被连接在一起,但有趣的是,这不能用operator +来完成:

#include <iostream>
#include <string>
int main() {
std::string str = "hello " + "world";
std::cout << str;
}

这将无法编译。
观看直播


为什么在语言中会有这种行为? 我的理论是,它允许使用多个#include语句构造字符串#include因为语句需要在自己的行上。 由于语言的语法,这种行为是否只是可能的,还是为了帮助解决问题而添加的异常?

相邻的字符串文字是串联的,我们可以在2.2翻译阶段的第6段C++标准部分的草案中看到这一点,其中说:

相邻的字符串文本标记连接在一起

在另一种情况下,没有定义运算符 + 来获取两个 *const 字符**。

至于为什么,这来自C,我们可以去国际标准的基本原理 - 编程语言 - C,它在6.4.5字符串文字部分说:

通过使用反斜杠换行符行延续,可以跨多行继续字符串,但这要求字符串的延续从下一行的第一个位置开始。为了允许更灵活的布局,并解决一些预处理问题(参见§6.10.3),C89委员会引入了字符串文字连接。将一行中的两个字符串文本粘贴在一起,中间没有空字符,以形成一个组合字符串文本。C语言的这一新增功能允许程序员将字符串文字扩展到物理行的末尾之外,而不必使用反斜杠换行机制,从而破坏程序的缩进方案。未引入显式串联运算符,因为串联是词法构造,而不是运行时操作。

如果没有此功能,则必须执行此操作才能在多行上继续字符串文字:

std::string str = "hello 
world
!";

这很丑陋。

就像@erenon说的,编译器会将多个字符串文字合并为一个,如果你想像这样使用多行,这特别有用:

cout << "This is a very long string-literal, "
"which for readability in the code "
"is divided over multiple lines.";

但是,当您尝试使用operator+将字符串文字连接在一起时,编译器会抱怨,因为没有为两个char const *定义operator+。运算符是为string类定义的(与 C 字符串完全不同),因此这样做是合法的:

string str = string("Hello ") + "world";

编译器自动将字符串文本连接成单个文本。

当编译器看到"hello " + "world";正在寻找一个全局+运算符时,这需要两个const char*...而且由于默认情况下没有,因此会失败。

编译器将"hello " "world" "!"解析为单个字符串。这允许您在多行上写入串联字符串。

在第一个示例中,在编译正确开始之前,连续的字符串文本由魔术连接。编译器看到单个文本,就好像您编写了"hello world!"一样。

在第二个示例中,一旦编译开始,文本就变成了静态数组。不能将+应用于两个数组。

为什么在语言中会有这种行为?

这是 C 语言的遗产,它来自记忆是一种宝贵资源的时代。它允许您执行相当多的字符串操作,而无需动态内存分配(就像std::string这样的更现代的习语经常做的那样);这样做的代价是一些相当古怪的语义。