2017-06-10 78 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,一個只需要左值。

    相關問題