2016-10-05 61 views
19

下面的代碼編譯和運行,並且沒有警告是由兩種或GCC鐺發出:我可以在覆蓋虛擬函數的返回類型中丟失「const」嗎?

#include <iostream> 

struct Base { 
    virtual ~Base() = default; 
    virtual std::string const& get() = 0; 
}; 

struct Derived: Base { 
    virtual std::string& get() override { return m; } 
    std::string m; 
}; 

int main() 
{ 
    Derived d; 
    d.get() = "Hello, World"; 

    Base& b = d; 
    std::cout << b.get() << "\n"; 
} 

std::string&協與std::string const&呢?

+0

是有意義的,因爲如果需要,您可以簡單地重新應用調用方的常量。當然,你不能自動退回,所以相反的情況不會是這樣。 – xaxxon

+0

@xaxxon:是的,我真的很驚訝它的工作原理(從來沒有想過它!)......尤其是因爲CLion不幸在那裏發生了錯誤。爲此,我在跟蹤器上提出了一個錯誤。 –

+1

有趣的是,我發現它在DR1250中也被固定以允許不完整的類型:http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1250 – marcinj

回答

18

這在class.virtual規定,在最新的草案(n4606),我們看到:

10.3節7/壓倒一切的函數的返回類型應與覆蓋函數 或協變的返回類型與函數的類相同。如果D::f覆蓋了一個功能B::f,返回類型的功能 是協變,如果它們滿足以下條件的函數:

  • 兩者都是類型指針,兩者都是對類左值的引用,或兩者都是rvalue引用類
  • B::f返回類型的類是相同的類中的D::f返回類型的類,或者是一個明確的和可訪問的直接或間接的基類的類中的D::f
  • 返回類型
  • 指針或引用都具有相同的cv資格,並且返回類型D::f中的類別類別與返回類型B::f中的類別類型具有相同或更低的cv資格。

具體而言,最後一個點地址這裏正是如此:它是可以接受的壓倒一切類型失去const和/或volatile限定符(它不能但是,增益它們)。


注:如通過上文提到@george,第8段/用於防止這種不完整的類類型的工作,但是這是since fixed

相關問題