2017-05-30 2 views
3

Je suis en train de compiler un exemple de « Design Patterns » et je suis confronté au problème suivant:Puis-je créer le constructeur d'une classe dérivée constexpr si le constructeur de la classe de base n'est pas constexpr?

J'ai une classe de base MapSite:

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

et une salle de classe dérivée:

class Room : public MapSite final{ 

private: 
    unsigned int room_number; 

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

    virtual void Enter() override; 
}; 

d'une autre classe que je veux appeler la fonction

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

Quand je fais si je reçois l'erreur suivante:

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

donc je pensais que le problème peut être que le constructeur doit être constexpr pour appeler le constructeur de la chambre d'une autre fonction, mais réglage du constructeur à :

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

génère cette erreur:

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

Ma question fondamentale est de savoir si je peux ma ke un constructeur de classe dérivé constexpr, même si le constructeur de la classe de base ne l'est pas. Ou peut-être s'il y a un bien meilleur concept pour résoudre ce problème.

PS: make_unique est un C++ 14 fonctionnalité que j'imité d'ici How to implement make_unique function in C++11? C++ 11, que je suis en compilant avec

+0

Demandez-vous: qu'est-ce que c'est que ce code essaie même d'utiliser 'Room' dans une expression constante et pourquoi? – Barry

Répondre

8

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

Non, vous ne pouvez pas.

Une fonction constexpr ne peut pas appeler des fonctions non-constexpr. Un constructeur doit appeler tous les constructeurs de sous-objets (y compris les sous-objets de base). Par conséquent, tous les constructeurs de sous-objets doivent être constexpr ou bien le constructeur d'objet complet peut ne pas être constexpr. Cela dit, votre problème original est séparé, et est couvert par la réponse de NathanOliver.

10

La question ici est pas Room a besoin d'un constructeur constexpr mais vous êtes passer une valeur à un modèle qui attend un type. dans

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

la partie Room(n) essaye de construire un Room et l'utiliser comme un paramètre de modèle pour make_unique. Ce n'est pas ce que tu veux faire. make_unique attend un type car il construit un std::unique_ptr de ce type à partir des paramètres que vous lui passez. Si vous voulez construire un Room avec n puis utilisez-vous

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