Unfortunately shape<int>
and shape<double>
are distinct, separate classes and therefore one cannot automatically use them interchangeably.
So you can either make another unique base class for all the templates:
class abstract_shape { };
template<class T>
class shape : public abstract_shape { };
With this design you can actually store pointers all classes derived from any shape<T>
in a variable of type abstract_shape*
.
abstract_shape* my_shape1 = &my_double_rect;
abstract_shape* my_shape2 = &my_int_rect;
If this does not solve the problem or does not fit the design, one can opt for a std::variant
based solution:
using shape_ptr = std::variant<std::nullptr_t, shape<int>*, shape<double>*>;
shape_ptr my_shape1 = &my_double_rect;
shape_ptr my_shape2 = &my_int_rect;
A third option is to store the shapes derived from shape<int>
and shape<double>
separately, and then templatize the functions which uses them:
std::vector<std::unique_ptr<shape<int>>> my_int_shapes;
std::vector<std::unique_ptr<shape<double>>> my_double_shapes;
template<class T>
auto do_something_with_shape(shape<T>* obj);
auto do_something_with_all_shapes() {
for (auto& int_shape : my_int_shapes) {
do_something_with_shape(int_shape.get());
}
for (auto& double_shape : my_double_shapes) {
do_something_with_shape(double_shape.get());
}
}