2017-10-17 70 views
1

在這裏面的代碼:不能讓一個「非const的範圍」一個const成員函數

int main(int argc, char *argv[]) 
{ 
    class Bar { 
    public: 
    int bar; 
    }; 
    class Foo { 
    public: 
     std::vector<Bar> myBars; 
     Bar &getOneBar() const { 
     for(Bar &bar : myBars) { 
      return bar; 
     } 
     } 
    }; 
} 

我得到一個編譯錯誤:

error: binding ‘const main(int, char**)::Bar’ to reference of type ‘main(int, char**)::Bar&’ discards qualifiers 

這我接受,但不要」不明白,因爲我沒有修改該函數中類的內容。我明白我可以在調用getOneBar()之後修改對象,但不能在裏面。

我有一個const_cast會得到解決,但我有點不喜歡這樣。

Bar &getOneBar() const { 
     for(Bar &bar : myBars) { 
      return const_cast<Bar &>(bar); 
     } 
     } 
+0

對於(Bar const&bar:myBars)'不會比鑄造好嗎? (和返回從'const'功能的非const引用似乎很奇怪我。) –

+0

這沒有什麼區別,我得到同樣的錯誤 –

回答

3

I understand that I could modify the object after the call to getOneBar(), but not inside.

這只是不允許的。更確切地說,const成員函數中的數據成員被認爲是const。然後myBars變得const std::vector<Bar>,並返回元素從它變得太const;它不匹配的返回類型Bar &,你不能到非const的引用綁定到const

正如你所說,const_cast是一個壞主意。更清晰的方式應該是聲明const和非const成員函數過載,例如

const Bar& getOneBar() const { 
    for (const Bar &bar : myBars) { 
     return bar; 
    } 
} 

Bar& getOneBar() { 
    for (Bar &bar : myBars) { 
     return bar; 
    } 
} 
+0

我@songyuanyao同意,但我不明白的是,爲什麼我一定會輸當我使用第二個重載時,如果我唯一想要的是找到一個欄,並且該操作不會更改我的對象,則第一次重載的const優化。 –

+1

@Santilín返回一個可能被修改的引用只會使'const'成員函數產生矛盾和混亂,這是沒有意義的。 – songyuanyao

相關問題