为什么我们不能同时实现 `getAB() &&` 和 `getAB()` 方法?

Why can't we implement both methods `getAB() &&` and `getAB()`?

为什么我们不能实现 getAB() &&getAB() 这两种方法,但可以实现其中任何一种?

  1. 作品:http://ideone.com/4EgObJ

代码:

struct Beta {
  Beta_ab ab;
  Beta_ab && getAB() && { cout << "1"; return move(ab); }
};

int main() {    
    Beta_ab ab = Beta().getAB();

    return 0;
}

  1. 作品:http://ideone.com/m9d0Tz

代码:

struct Beta {
  Beta_ab ab;
  Beta_ab && getAB() { cout << "2"; return move(ab); }
};

int main() {
    Beta b;
    Beta_ab ab = b.getAB();

    return 0;
}

  1. 有效:http://ideone.com/QIQtZ5

代码:

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

为什么前两个示例代码有效,但最后一个示例无效?

标准款[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 ]

我并不完全清楚为什么要制定这条规则,但事实就是如此。 (虽然我猜尝试在重载决议规则中加入一些东西的替代方案至少需要一些工作。)

解决方案很明显:向您的 "2" 重载添加一个左值 (&) 引用限定符,这样一个只接受右值,一个只接受左值。