为什么 std::string 的成员 operator= 不是左值引用限定的

Why is std::string's member operator= not lvalue ref-qualified

我最近 that member functions can be ref-qualified,这让我可以写

struct S {
    S& operator=(S const&) & // can only be used if the implicit object is an lvalue
    { 
      return *this; 
    }
};

S operator+(S const &, S const &) { 
  return {}; 
}

从而防止用户做类似

的事情
S s{};
s + s = S{}; // error

但是,我看到 std::string 的成员 operator= does not do this。所以下面的代码编译时没有警告

std::string s;
s + s = s;

是否有允许这样做的理由?

如果没有,将来是否可以添加 ref-qualifier,或者会不会以某种方式破坏现有代码?

不能确定为什么标准不禁止您提出的行为,但有一些可能的解释:

  1. 这只是C++11中的一个疏忽。在 C++11 之前没有引用限定方法,所以有人忘记改变标准中的行为。

  2. 保留它是为了向后兼容那些使用 'dirty' 代码的人,例如:

std::string("a") = "gds";

出于一些奇怪的原因。

关于将来添加这个 - 这是可能的。但是首先旧的 operator= 必须被弃用,然后被删除,因为它会导致像上面的代码无法编译。即便如此,一些编译器可能会支持它以实现向后标准兼容性

很可能,时机在这个决定中发挥了作用。 Ref 限定的成员函数被添加到 C++11 的语言中,而 std::string 自 C++98 以来就一直存在。更改标准库中某些内容的定义并不是一件容易的事情,因为它可能会不必要地破坏现有代码。在这种情况下,人们不应该专门研究为什么应该允许这种奇怪的分配(即寻找用例)。相反,人们还应该看看为什么不允许这种奇怪的分配(即看看好处,并权衡它们与其他工作代码中断时的潜在痛苦)。这种变化多久会对现实的编码场景产生影响?

查看评论,与一个提议的用例相反的是 "They could just [another approach]." 是的,他们可以,但如果他们不这样做呢?在最初设计结构 (std::string) 时,提出备选方案是富有成效的。但是,一旦该结构得到广泛使用,您就必须考虑当前未使用替代结构的现有代码。对你可能造成的痛苦有足够的好处吗?这种变化真的会经常发现错误吗?在不会触发另一个警告的情况下,此类错误有多常见? (举个例子,在 if 语句的条件中使用赋值而不是相等很可能已经生成了警告。) 这些是语言的一些问题设计师拼搏。

请理解,我不是说不能改,只是需要慎重考虑。