Reputation: 71
I'm trying to make a constructor in C++ (C++17 is fine), which has one argument, and I want this argument to be inherited from two types.
So I have this struct:
struct SceneNodeData {
Drawable* drawable;
Transformable* transformable;
SceneNodeData(
Drawable* drawable,
Transformable* transformable
) : drawable(drawable), transformable(transformable) {}
};
But for convenience I want another constructor, with only one parameter, which is Drawable
and Transformable
at the same time (like Sprite
):
struct SceneNodeData {
Drawable* drawable;
Transformable* transformable;
SceneNodeData(
<Drawable, Transformable>* drawableAndTransformable
) : drawable(drawableAndTransformable), transformable(drawableAndTransformable) {}
};
Is there any way to do this in C++ ?
Upvotes: 3
Views: 70
Reputation: 180500
You can use a template and constarin the type using the type trait std::is_convertible
to check if the type provided can be cast to both types. That would look like
struct SceneNodeData {
Drawable* drawable;
Transformable* transformable;
template<typename T, std::enable_if_t<std::is_convertible_v<T*, Drawable*> &&
std::is_convertible_v<T*, Transformable*>, bool> = true>
SceneNodeData(T* drawableAndTransformable) : drawable(drawableAndTransformable), transformable(drawableAndTransformable) {}
};
Upvotes: 4
Reputation: 119144
Not quite, but:
DrawableTransformable
publicly derived from both Drawable
and Transformable
, and have your constructor take an argument of type DrawableTransformable*
. Any concrete class derived from DrawableTransformable
would need to implement the pure virtual functions from both Drawable
and Transformable
.T*
with an SFINAE check that T
is publicly derived from both Drawable
and Transformable
. Or you could omit the SFINAE check and simply let a hard error occur in the initialization of drawable
and transformable
.Upvotes: 3