2017-05-30 197 views
3

我想從「設計模式」編譯一個例子,我面臨着以下問題:如果基類構造函數不是constexpr,我可以構造派生類constexpr的構造函數嗎?

我有一個基類網站地圖:

class MapSite{ 
public: 
    MapSite(); 
    virtual ~MapSite(); 
    virtual void Enter() = 0; 
}; 

和派生類中房:

class Room : public MapSite final{ 

private: 
    unsigned int room_number; 

public: 
    Room(unsigned int rn) : room_number(rn) {}; 

    virtual void Enter() override; 
}; 

從另一個類我要調用的函數

virtual std::unique_ptr<Room> MakeRoom(unsigned int n) {return make_unique<Room(n)>();} 

當我這樣做,我得到以下錯誤:

error: temporary of non-literal type ‘Room’ in a constant expression 
    virtual std::unique_ptr<Room> MakeRoom(unsigned int n) {return unique::make_unique<Room(n)>();} 

所以我想這個問題可能是在構造函數必須是constexpr爲了從另一個函數調用間的構造函數,但構造函數設置:

constexpr Room(unsigned int rn) : room_number(rn) {}; 

會產生這樣的錯誤:

error: call to non-constexpr function ‘MapSite::MapSite()’ 
    constexpr Room(unsigned int rn) : room_number(rn) {}; 

我的基本問題是,我能否馬ke是派生類構造函數constexpr,即使基類構造函數不是。或者,如果有更好的概念來解決這個問題。

PS:make_unique是一個C++ 14功能,我從這裏How to implement make_unique function in C++11?爲C++ 11,模擬其我與

+0

問問自己:那些甚至試圖在常量表達式中使用'Room'的代碼是什麼?爲什麼? – Barry

回答

8

Can i make the constructor of a derived class contexpr if the base class constructor is not constexpr?

不,你不能。

一個constexpr函數不能調用非constexpr函數。構造函數必須調用所有的子對象(包括基礎子對象)的構造函數。因此,所有的子對象構造函數都必須是constexpr,否則完整的對象構造函數可能不會被constexpr。

這就是說,你原來的問題是分開的,並且由NathanOliver的答案覆蓋。

10

這裏的問題是編譯不是Room需要constexpr構造函數,但你將值傳遞給期望類型的模板。在

virtual std::unique_ptr<Room> MakeRoom(unsigned int n) {return make_unique<Room(n)>();} 

Room(n)部分嘗試構建一個Room,並用它作爲make_unique模板參數。這不是你想要做的。 make_unique需要一個類型,因爲它會根據傳遞給它的參數構造該類型的std::unique_ptr。如果你想構建一個Roomn然後使用

virtual std::unique_ptr<Room> MakeRoom(unsigned int n) {return make_unique<Room>(n);} 
相關問題