Suppose you have some classes like Circle
, Image
, Polygon
for which you need to enforce a common interface that looks like this (not real code):
struct Interface {
virtual bool hitTest(Point p) = 0;
virtual Rect boundingRect() = 0;
virtual std::string uniqueId() = 0;
}
so for example the Circle
class would like:
struct Circle {
// interface
bool hitTest(Point p) override;
Rect boundingRect() override;
std::string uniqueId() override;
double radius() const;
Point center() const;
// other stuff
}
I would like to use std::variant<Circle, Image, Polygon>
to store instances of my classes in a std::vector
and then use it like this:
using VisualElement = std::variant<Circle, Image, Polygon>;
std::vector<VisualElement> elements;
VisualElement circle = MakeCircle(5, 10);
VisualElement image = MakeImage("path_to_image.png");
elements.push_back(circle);
elements.push_back(image);
auto const &firstElement = elements[0];
std::cout << firstElement.uniqueId() << std::endl;
Using inheritance I could do this by creating a base class and then each of my classes would become a subclass of the base (and obviously if a derive class doesn't implement the interface the program wouldn't compile). Then instead of using variants, I could use smart pointers to store the instances in a vector (e.g. std::vector<std::unique_ptr<BaseElement>>
). I would like to avoid this, so I'm wondering what would be the best way (if there is any) to enforce the same design using std::variant
and C++20.