为什么 std::string append 没有在 rval ref 上超载?

Why std::string append is not overloaded on rval ref?

我很熟悉,append in std::string returns std::string& 因此它不符合移动的条件,所以结果不会感动了。

#include <string>


int main()
{
    std::string s = std::string("A").append("B");
    return s.size();
}

https://godbolt.org/z/M63aWW

#include <string>


int main()
{
    std::string s = std::move(std::string("A").append("B"));
    return s.size();
}

https://godbolt.org/z/jTnsac

你可以看到,后一个示例将产生更少的分配,因此在这种情况下,最好移动一些看起来像临时的东西。我的问题是,为什么他们(委员会)不在 && 上添加简单的重载以使 append 的结果根据上下文为 std::string&std::string&&?我的意思是类似于 std::optional 的东西正在用 value 做。有没有例子可以证明这种优化是假的?

您不能简单地添加 && 重载。您还必须创建原始函数 &。这可能是一个重大变化。

所有这些都是为了很少的收获。由于 append() 修改了源字符串并且 returns *this 更多地用于链接而不是将结果分配给其他任何内容,因此您编写的代码是不合常理的。如果需要,请使用 +,这是为表达式结果构建字符串的惯用形式,并且已经具有必要的重载以提高效率:

auto s = "A"s + "B";

正如 P1165R1 中所述,basic_stringoperator+ 的分配器传播规则很复杂,并且是不同库实现不一致的根源。

Make stateful allocator propagation more consistent for operator+(basic_string)

[...] Allocator propagation for basic_string’s operator+ is haphazard, inconsistent, and a source of implementation divergence. Let's make them consistent. [...]

P1165R1 已被 C++20 接受。

append() 成员函数没有相同的语义,没有重载,也没有 “随意性......” operator+(P1165R1 之前)。前者没有理由加入后者的领域; basic_string 已经是一个容器的怪物(你的反例 optional 不是这种情况,它不是标准意义上的容器,即使它具有类似于 stl 容器的语义) .