“std::string + char” 表达式会创建另一个 std::string 吗?

5
下面的表达式是否会创建另一个 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”表达式?

5
您的问题标题与问题详情不符。 - Brian Bi
1
它们的速度一样快,没有区别。 - πάντα ῥεῖ
6
“fix”是什么意思?问题是什么?此外,在这里,堆栈/堆是具有误导性/错误的/不相关的,特别是因为std::string动态分配其缓冲区。 - Lightness Races in Orbit
2
s1 = s2 + 'b';s1 += s2; s1 += 'b'; 通常不会做相同的事情。只有当 s1 最初为空时,它们最终才会产生相同的效果,但如果已知 s1 为空,则写 s1 += s2; 而不是 s1 = s2; 没有意义。 - user743382
1
@Muscampester:显然,在编辑之前就被踩了。 - Lightness Races in Orbit
显示剩余5条评论
2个回答

4
所有涉及到 std::string 的重载 + 运算符都会返回一个新的 std::string 对象。当你最终解密相关文档后,这将是你不可避免的结论。
因此,在你问题中的第一个例子中,+ 运算符将返回一个临时对象,在紧随其后的 += 操作完成后将被销毁。
话虽如此:C++ 编译器可以采用任何产生相同可观测结果的优化。通过将代码的第一个版本转换为第二个版本,从而避免创建临时对象的需求,这是可能的。我认为这不太可能发生,但这是有可能的。在两个版本的代码结果中没有可观测的差异,因此该优化是公平的。
但是,从技术上讲,+ 操作会产生一个临时的 std::string 对象。

0

根据上下文而定。在您的代码片段中,不会有另一个对象,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 连接起来


3
你确定吗?在我看来,s2 + 'b' 看起来像是一个独立的临时 std::string。真正的答案是“谁在乎”,因为最坏的情况下这个临时变量会被移动到 s1 中。 - Lightness Races in Orbit
3
这个语法叫做“拷贝初始化”,所以 result 是一个连接 s1s2 的新临时对象的副本。在 C++03 中是拷贝构造,而在 C++11 及以后版本中是移动构造。 - Ben Voigt
3
不是那个原因。有一个operator+过载函数可以接受一个字符串和一个单一字符作为参数,但是单一字符不会被隐式转换为字符串。大家谈论的额外临时变量就是来自operator+的返回值。 - Ben Voigt
@LightnessRacesinOrbit 来自 += 操作符:向字符串追加内容 通过将额外的字符附加到当前值的末尾来扩展该字符串: (有关其他附加选项,请参见成员函数 append)。 - paweldac
@paweldac:在 [over.ics.rank] 章节中,“标准转换序列 S1 比标准转换序列 S2 更好的条件是... S1S2 都是引用绑定,并且都不是指向没有 ref-qualifier 声明的非静态成员函数的隐式对象参数,而且 S1 绑定到一个右值引用,S2 绑定到一个左值引用。” 这个规则强制编译器优先选择移动构造函数而不是复制构造函数,因为 std::string 同时具有这两种构造函数。 - Ben Voigt
显示剩余16条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接