【问题标题】:Does "std::string + char" expression create another std::string?“std::string + char”表达式是否会创建另一个 std::string?
【发布时间】:2016-12-27 22:56:52
【问题描述】:

下面的表达式是否会创建另一个 std::string 然后将其添加到 s1 中?

    std::string s1 = "abc", s2 = "xyz";
    s1 += s2 + 'b';

是否应该防止这种情况(它们会被添加到 s1 而不需要额外的工作)?

    std::string s1 = "abc", s2 = "xyz";
    s1 += s2;
    s1 += 'b';

这些规则是否也适用于“std::string + std::string”表达式?

【问题讨论】:

  • 您的问题标题与问题详情不符。
  • 这些速度同样快。没有区别。
  • “修复”是为了什么?问题是什么?此外,堆栈/堆在这里具有误导性/错误/无关紧要,特别是因为 std::string 动态分配其缓冲区。
  • s1 = s2 + 'b';s1 += s2; s1 += 'b'; 通常不会做同样的事情。它们只有在最初 s1 为空时才会产生相同的效果,但如果已知 s1 为空,则编写 s1 += s2; 而不是 s1 = s2; 是没有意义的。
  • @LightnessRacesinOrbit "std::string 动态分配其缓冲区" 具有误导性,因为它可能使用小字符串优化。

标签: c++ performance memory


【解决方案1】:

所有涉及std::string 的重载+ 运算符都返回一个新的std::string 对象。这是you finally decipher the relevant documentation时你必然得出的结论。

因此,在您问题的第一个示例中,+ 运算符将返回一个临时对象,该对象将在紧随其后的+= 操作完成后被销毁。

话虽如此:C++ 编译器可以使用任何产生相同可观察结果的优化。 C++ 编译器很可能会发现可以通过将代码的第一个版本转换为第二个版本来避免创建临时对象的需要,本质上。我认为这不太可能,但有可能。两个版本的代码之间的结果没有明显差异,因此优化是公平的游戏。

但是,从技术上讲,+ 操作会生成一个临时的 std::string 对象。

【讨论】:

    【解决方案2】:

    取决于上下文。在您的代码 sn-p 中不会有另一个对象,s2'b' 将附加到已经存在的 s1

    http://www.cplusplus.com/reference/string/string/operator+=/

    例如在这种情况下:

    std::string s1 = "abc";
    std::string s2 = "zxy";
    std::string result = s1 + s2;
    

    result 是连接s1s2 的新对象

    【讨论】:

    • 你确定吗? s2 + 'b' 对我来说就像一个独特的临时 std::string。真正的答案是“谁在乎”,因为在最坏的情况下,该临时文件将被移至s1
    • @LightnessRacesinOrbit:是的,它会创建一个临时对象,构造函数采用单个字符
    • 该语法是“复制初始化”,因此result 是一个(C++03:复制,C++11 及更高版本:移动)连接s1s2.
    • @Raindrop7:这不是原因。 operator+ 的重载采用字符串和单个字符,单个字符不会隐式转换为字符串。每个人都在谈论的额外临时是来自operator+的返回值。
    • @BenVoigt:“C++03:复制,C++11 及更高版本:移动”在 C++17 中,两者都不是。由于保证省略,结果直接在result 中创建。
    猜你喜欢
    • 1970-01-01
    • 2011-11-13
    • 1970-01-01
    • 1970-01-01
    • 2012-06-09
    • 2018-03-11
    • 2017-03-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多