为什么不允许在一个ref-qualifier上超载?

Leo*_*aar 13 c++ overloading rvalue language-lawyer c++11

显然,不允许在ref-qualifiers上重载 - 如果删除&或者&&(只是标记,而不是它们的函数),这段代码将无法编译:

#include <iostream>

struct S {
    void f() &  { std::cout << "Lvalue" << std::endl; }
    void f() && { std::cout << "Rvalue" << std::endl; }
};

int main()
{
    S s;
    s.f();   // prints "Lvalue"
    S().f(); // prints "Rvalue"
}
Run Code Online (Sandbox Code Playgroud)

换句话说,如果您有两个具有相同名称和类型的函数,则必须定义两者,如果您定义其中任何一个.我认为这是故意的,但是原因是什么?例如,为什么不允许调用&&rvalues 的版本(如果已定义),以及f()以下变体中的其他所有内容的"primary" (反之亦然 - 尽管这会让人感到困惑):

struct S {
    void f()    { std::cout << "Lvalue" << std::endl; }
    void f() && { std::cout << "Rvalue" << std::endl; }
};
Run Code Online (Sandbox Code Playgroud)

换句话说,让它们的行为类似于主模板的模板特化.

M.M*_*M.M 9

这与以下情况没有任何不同:

struct S {};

void g(S s);
void g(S& s);

int main()
{
    S s;
    g(s);     // ambiguous
}
Run Code Online (Sandbox Code Playgroud)

过载分辨率一直都是这样的; 通过引用传递不是优先传递值(反之亦然).

(ref-qualified函数的重载分辨率就好像它是一个带有隐式第一个参数的普通函数,其参数是*this; lvalue-ref qualified就像第一个参数S &,const &就像是S const &等等)

我猜你说这g(s)应该打电话g(S&)而不是模棱两可.

我不知道确切的基本原理,但是重载决策很复杂,因为它没有添加更多特殊情况(特别是那些可能无声编译而不是编码器的意图).

当你在你的问题指出,这个问题可以很容易地通过使用两个版本避免S &S &&.