#include namespace detail { template void destructor_wrapper(Base* value) { static_cast(value)->~Type(); } template struct contains_type { static constexpr bool value = std::is_same::value || contains_type::value; }; template struct contains_type : std::is_same {}; } // namespace detail template class in_place {}; template class covariant_t { public: template explicit covariant_t(in_place /*tag*/, Args&&... args) : dtor{&::detail::destructor_wrapper} { static_assert(::detail::contains_type::value, "Instantiated constructor must inherit from `Base`"); new(&storage) Ctor(std::forward(args)...); } ~covariant_t() { dtor(base()); } covariant_t(const covariant_t&) = delete; auto operator=(const covariant_t&) = delete; auto operator*() -> auto& { return *base(); } auto operator*() const -> auto& { return *base(); } auto operator->() { return base(); } auto operator->() const { return base(); } private: auto base() { return static_cast(static_cast(&storage)); } std::aligned_union_t<1, Storage...> storage; void(*dtor)(Base*); };