Search code examples
c++operator-overloadingstdstringref-qualifier

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


I recently learned that member functions can be ref-qualified, which allows me to write

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 {}; 
}

thereby preventing users from doing things like

S s{};
s + s = S{}; // error

However, I see that std::string's member operator= does not do this. So the following code compiles with no warnings

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

Is there a reason for allowing this?

If not, would it be possible to add the ref-qualifier in the future, or would that break existing code somehow?


Solution

  • Likely, the timing plays a role in this decision. Ref-qualified member functions were added to the language with C++11, while std::string has been around since C++98. Changing the definition of something in the standard library is not something to be undertaken lightly, as it could needlessly break existing code. This is not a situation where one should exclusively look at why this weird assignment should be allowed (i.e. look for a use-case). Rather, one should also look at why this weird assignment should be disallowed (i.e. look at the benefits, and weigh them against the potential pain when otherwise working code breaks). How often would this change make a difference in realistic coding scenarios?

    Looking at the comments, a counter to one proposed use-case was "They could just [another approach]." Yes, they could, but what if they didn't? Proposing alternatives is productive when initially designing the structure (std::string). However, once the structure is in wide use, you have to account for existing code that currently does not use the alternative. Is there enough benefit for the pain you could cause? Would this change actually catch mistakes often enough? How common are such mistakes in contexts where another warning would not be triggered? (As one example, using assignment instead of equality in the conditional of an if statement is likely to already generate a warning.) These are some of the questions with which the language designers grapple.

    Please understand that I am not saying that the change cannot be done, only that it would need to be carefully considered.