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
source to share
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.
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);}
source to share