为什么 std::string append 不会在 rval ref 上重载?

kos*_*sky 4 c++ stdstring rvalue-reference stdoptional

我熟悉,appendinstd::string返回std::string&,因此它没有资格被移出,所以结果不会被移动。

#include <string>


int main()
{
    std::string s = std::string("A").append("B");
    return s.size();
}
Run Code Online (Sandbox Code Playgroud)

https://godbolt.org/z/M63aWW

#include <string>


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

https://godbolt.org/z/jTnsac

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

Seb*_*edl 7

您不能简单地添加&&重载。您也必须制作原始功能&。这可能是一个突破性的变化。

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

auto s = "A"s + "B";
Run Code Online (Sandbox Code Playgroud)

  • @koscelansky 检查“operator+”的[重载 6-12](https://en.cppreference.com/w/cpp/string/basic_string/operator%2B) - 它们在内部进行移动。 (2认同)

dfr*_*fri 7

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

使有状态分配器传播对于 operator+(basic_string) 更加一致

[...]为分配器传播basic_stringoperator+是杂乱无章的,不一致的,和实施发散的来源。让我们使它们保持一致。[...]

P1165R1 已被 C++20 接受。

append()成员函数并不具有相同的语义,是不是因为负荷过重而不会从同患“随意性...”operator+(前P1165R1)。前者没有理由加入后者的领域;basic_string已经是容器的怪物(您的反例不是这种情况optional,它不是标准意义上的容器,即使它具有类似于 stl 容器的语义)。