Why can't we implement both methods getAB() && and getAB(), but can implement any one of these?
Code:
struct Beta {
  Beta_ab ab;
  Beta_ab && getAB() && { cout << "1"; return move(ab); }
};
int main() {    
    Beta_ab ab = Beta().getAB();
    return 0;
}
Code:
struct Beta {
  Beta_ab ab;
  Beta_ab && getAB() { cout << "2"; return move(ab); }
};
int main() {
    Beta b;
    Beta_ab ab = b.getAB();
    return 0;
}
Code:
struct Beta {
  Beta_ab ab;
  Beta_ab && getAB() && { cout << "1"; return move(ab); }
  Beta_ab && getAB() { cout << "2"; return move(ab); }
};
int main() {
    Beta b;
    Beta_ab ab1 = b.getAB();
    Beta_ab ab2 = Beta().getAB();
    return 0;
}
Why are the first two examples of code works, but the last example does not work?
Standard section [over.load]/2.3:
Member function declarations with the same name and the same parameter-type-list as well as member function template declarations with the same name, the same parameter-type-list, and the same template parameter lists cannot be overloaded if any of them, but not all, have a ref-qualifier.
[Example:
class Y {
  void h() &;
  void h() const &;    // OK
  void h() &&;         // OK, all declarations have a ref-qualifier
  void i() &;
  void i() const;      // ill-formed, prior declaration of i
                       // has a ref-qualifier
};
-- end example ]
It's not entirely clear to me exactly why we have this rule, but that's what it is. (Though I guess the alternative of trying to work something into the overload resolution rules would take some work, at least.)
The solution is obvious: add an lvalue (&) ref-qualifier to your "2" overload so that one only takes rvalues and one only takes lvalues.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With