2017-06-10 50 views
6

为什么我们不能同时使用getAB() &&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; 
} 

  • 作品: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; 
    } 
    

  • Doen't作品: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; 
    } 
    

    为什么代码的第一两个例子作品,但最后一个例子不起作用?

    +0

    与您的问题无关,但在制作[MCVE](https://stackoverflow.com/help/mcve)时,请确保其中没有无关的错误。无关的错误会分散实际问题。我当然在谈论你在'main'函数中重新定义变量'ab'。 –

    +4

    如果有任何重载是引用限定的,那么_all_重载必须是引用限定的 - 将第二个重载更改为“Beta_ab && getAB()&{cout <<”2“;返回移动(ab); }'。 (不作为答案张贴,因为这肯定是一个骗局。) – ildjarn

    +1

    可以在左值*或右值上调用不带ref参数限定符的重载,例如'Beta_ab && getAB()'。rvalue ref限定符“Beta_ab && getAB()&&”的重载只能在rvalues上调用。因此,如果两者都允许共存,那么在右值上调用'getAB()'将会是*模糊的。 –

    回答

    8

    标准部[over.load] /2.3:

    具有相同名称和相同的参数型列表,以及具有相同名称的成员函数模板声明成员函数声明,则相同的参数类型列表,并且如果它们中的任何一个但不是全部具有参考限定符,则不能重载相同的模板参数列表。

    [示例:

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

    - 结束举例]

    这并不完全清楚,我到底为什么我们有这个规则,但它是什么。 (虽然我猜的努力工作,事到重载决策规则会采取一些工作,至少可替代)

    解决的办法是显而易见的:添加一个左值(&)REF-预选赛你"2"过载,使一个只需要rvalues,一个只需要左值。

    相关问题