为什么我可以构造一个包含多个字符串文字的字符串?

时间:2014-02-07 13:32:02

标签: c++ string concatenation grammar string-literals

#include <iostream>
#include <string>

int main() {
    std::string str = "hello " "world" "!";
    std::cout << str;
}

以下编译,运行和打印:

  

你好世界!

see live


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

#include <iostream>
#include <string>

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

这将无法编译 see live


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

5 个答案:

答案 0 :(得分:10)

相邻的字符串文字是连接的,我们可以在draft C++ standard部分2.2 翻译阶段 6 中看到这一点,其中说:

  

相邻的字符串文字标记是连接的

在你的另一种情况下,没有定义operator+来取两个* const char **。

至于为什么,这来自 C ,我们可以转到Rationale for International Standard—Programming Languages—C,它在6.4.5 字符串文字部分中说明:< / p>

  

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

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

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

非常难看。

答案 1 :(得分:7)

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

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

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

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

答案 2 :(得分:2)

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

答案 3 :(得分:0)

当编译器看到"hello " + "world";正在寻找一个全局+运算符,该运算符需要两个const char* ...并且因为默认情况下没有它失败。

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

答案 4 :(得分:0)

在第一个示例中,在编译正确启动之前,连续的字符串文字由magic连接。编译器会看到一个文字,就好像你写了"hello world!"

在第二个例子中,一旦编译开始,文字就变成了静态数组。您无法将+应用于两个数组。

  

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

这是C的遗产,它来自于记忆是宝贵资源的时代。它允许你在不需要动态内存分配的情况下进行大量的字符串操作(像std::string这样的更现代的习语经常这样做);价格是一些相当古怪的语义。