Can I make a constexpr derived class constructor if the base class constructor is not constexpr?

I am trying to compile an example from Design Patterns and I am facing the following problem:

I have a base MapSite class:

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

      

and the derived class:

class Room : public MapSite final{

private:
    unsigned int room_number;

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

    virtual void Enter() override;
};

      

From another class I want to call a function

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

      

When I do this, I get the following error:

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

      

So, I thought the problem might be that the constructor should be constexpr

in order to call the Room constructor from another function, but by setting the constructor to:

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

      

will result in this error:

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

      

My main question is: can I make a constexpr derived class constructor even though the base class constructor is not. Or maybe if there is a much better concept for solving this problem.

PS: make_unique is a C ++ 14 function that I imitate from here How do I implement make_unique function in C ++ 11? for C ++ 11 which I compile with

+3


source to share


2 answers


Can I make contexpr derived class constructor if base class constructor is not constexpr?

No, you cannot.



A constexpr function cannot call non-constexpr functions. The constructor must call all auxiliary objects (including base-subobjects). Therefore, all constructors of subobjects must be constexpr or otherwise the complete constructor of an object cannot be constexpr.

However, your original issue is separate and covered by NathanOliver's answer.

+8




The problem here isn't that you Room

need a constructor constexpr

, but you are passing a value to a template expecting a type. in

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

      



part Room(n)

tries to build Room

and use it as a template parameter for make_unique

. This is not what you want to do. make_unique

expects a type when it constructs a of std::unique_ptr

that type from the parameters you pass to it. If you want to build Room

with n

then you use

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

      

+10


source







All Articles