为什么我可以构造具有多个字符串文本的字符串?
Why can I construct a string with multiple string literals?
#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
这样的更现代的习语经常做的那样);这样做的代价是一些相当古怪的语义。
- 如何在C++中用std::cout正确显示带十六进制的字符串文本
- 在编译时检查字符串文本的长度
- 读取字符串文本输入以创建 2D 矢量
- 管理字符串文本的最佳做法
- 定义宏以将前缀 0x 添加到十六进制字符串文本
- 无法在模板参数中定义字符串文本
- 不推荐使用 PTCHAR 的字符串文本
- C++ 字符串文本和常量
- C++20字符串文本模板参数工作示例
- 返回从字符串文本创建的静态string_view是否安全?
- 在处理任何字符大小的模板中使用字符串文本
- 是否保证相同内容字符串文本的存储相同?
- 将以 null 结尾的字节字符串转换为原始字符串文本
- 是否可以创建一个用户定义的文本,将字符串文本转换为 own 类型的数组?
- 使用C++中的模板检测不同的字符串文本
- 无法完全专用化字符串文本的模板
- C++ - 确定 const char* 是指向字符串文本对象还是动态对象
- 是否可以在原始字符串文本中插入转义序列?
- C++带有捕获组的正则表达式字符串文本
- 为什么多维数组中的空字符串文本衰减为空指针?