为什么std::字符串的成员运算符=不是左值引用限定的

人气:381 发布:2022-10-16 标签: operator-overloading c++ stdstring ref-qualifier

问题描述

我最近learned成员函数可以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限定符,或者这会以某种方式破坏现有代码吗?

推荐答案

时间可能在这一决定中发挥作用。引用限定的成员函数是用C++11添加到语言中的,而std::string从C++98开始就存在了。更改标准库中某些东西的定义不是一件轻而易举的事情,因为这可能会不必要地破坏现有代码。在这种情况下,人们不应该只考虑为什么应该允许这种奇怪的分配(例如,寻找用例)。相反,人们还应该考虑为什么应该不允许这种奇怪的任务(即,查看好处,并权衡它们与其他工作代码崩溃时的潜在痛苦)。此更改多久会在实际编码方案中产生影响?

查看评论,一个提议的用例的反面是"他们可以只是[另一种方法]。"是的,他们可以,但如果他们不这样做呢?在最初设计结构(std::string)时,提出替代方案是有成效的。然而,一旦该结构被广泛使用,您就必须考虑到当前未使用该替代方法的现有代码。对于你可能引起的疼痛,有足够的好处吗?这种改变真的能足够频繁地捕捉到错误吗?在不会触发另一个警告的上下文中,这种错误有多常见?(例如,在if语句的条件中使用赋值而不是相等很可能已经生成了警告。)这些是语言设计人员努力解决的一些问题。

请理解,我并不是说不能进行更改,只是需要仔细考虑。

450