c++ - 这两种添加字符串的情况有什么区别?

标签 c++ string c++11

我注意到当我初始化一个字符串时,编译器报告了一个我没有预料到的错误。

例如:

#include <iostream>
#include <string>

using namespace std;

int main() {
    string s1 = "Hello", s2 = "World!"; // ok
    string s3 = s1 + ", " + "World!"; // ok
    string s4 = "Hello" + ", " + s2; // error
    cout << s1 + " " + s2 << endl; //ok
    return 0;
}

对我来说,如果 s3 工作正常,s4 应该也能正常工作。

为什么会出现该错误?这两个初始化字符串(s3s4)有什么区别?

最佳答案

"Hello" 不是 std::string(而是 const char[6],而 ", "const char[3]) 并且 std::string+ 运算符不适用。

这是 C++ 的一个小不便,源于它的 C 血统。这意味着在通过 + 连接字符串时,您必须确保其两个操作数中至少有一个实际上是 std::string,如

auto s = std::string{"Hello"} + ", " + "World";

其中第一个 + 有一个 std::string 作为它的第一个操作数,因此产生一个 std::string,所以第二个 + 也有一个 std::string 作为它的第一个操作数(因为 + 是从左到右处理的)。


Edit1T.C. 的评论提示,我提到如果仅用空格分隔,C 字符串文字会自动连接:

std::string s = "Hello" ", " "World";

这个行为也是从 C 继承而来的:预处理器将上面的代码呈现给

std::string s = "Hello, World";

在编译器正确处理它之前(更准确地说,字符串连接发生在翻译的 phase 6 中,就在编译之前)。这实际上是连接原始字符串文字的最简单因此也是最方便的方法。但请注意,我必须声明 s 的类型,因为 auto 推导会给出 const char*


Edit2PaperBirdMaster 的评论提示,我提到自 C++14 起,您可以通过简单地在字符串后添加 s 直接形成 std::string 文字,如果您拉入相关的operator""s (或周围的命名空间)。

using std::literals::operator""s;                // pull in required operator
const auto s = "Hello"s + ", " + "World";        // std::string

参见 this post至于为什么所需的 operator""s 隐藏在嵌套的命名空间中。另请注意,除了 using std::literals::operator""s; 之外,您还可以引入周围的 namespace:以下任一声明都可以。

using namespace std::string_literals;
using namespace std::literals::string_literals;
using namespace std::literals;

这不像普通的 using namespace std; 那样糟糕(而且该死)。

关于c++ - 这两种添加字符串的情况有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32555142/

相关文章:

c++ - 为什么 make_unique to vector::back() 创建另一个拷贝?

c++ - 使用不同的模板参数调用模板类的对象

c++ - 无法解析函数 'sqrt' - Eclipse for Windows

c++ - 遍历模板参数包,不带参数的特化有什么作用?

c++ - 重载加号运算符的正确方法是什么?

c++ - 这个赋值运算符后面的 & 是什么意思?

c++ - 在 C++ 的编译期间成员函数是否可用?

string - 检测重叠范围并在 oracle 中纠正

Java Thread ,答案是A怎么来的?

java-如何将 ArrayList<ArrayList<String>> 转换为 String[]][]