Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Function argument inheriting two types simultaneously

Tags:

c++

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++ ?

like image 385
Ekz Avatar asked Sep 14 '26 22:09

Ekz


2 Answers

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) {}
};
like image 146
NathanOliver Avatar answered Sep 16 '26 10:09

NathanOliver


Not quite, but:

  • You could define a class 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.
  • You could define a constructor template taking 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.
like image 24
Brian Bi Avatar answered Sep 16 '26 12:09

Brian Bi



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!