I have an abstract class
template struct A { /* virtual methods */ };
and several concrete derived classes with various con
We can solve this using SFINAE and the std::is_constructible type trait (h/t Yakk).
We just need one single create function, that will dispatch out to other functions:
template <class... Args>
static std::shared_ptr<A> create( id_type id, Args&&... args )
{
switch (id) {
case Type_B:
return create<B>(std::forward<Args>(args)...);
case Type_C:
return create<C>(std::forward<Args>(args)...);
// ...
}
Each tag-based create
function will either call the correct constructor OR return nullptr if such a one does not exist:
// possible to construct
template <typename T, typename... Args>
std::enable_if_t<
std::is_constructible<T, Args...>::value,
std::shared_ptr<T>
>
create(Args&&... args) {
return std::make_shared<T>(std::forward<Args>(args)...);
}
// impossible to construct
template <typename T, typename... Args>
std::enable_if_t<
!std::is_constructible<T, Args...>::value,
std::shared_ptr<T>
>
create(Args&&... ) {
return nullptr;
}