#include <tuple>
#include <iostream>
class Base
{
public:
virtual ~Base(void){}
};
class Derived1 : public Base
{
public:
Derived1(int) {}
virtual ~Derived1(void){}
};
class Derived2 : public Base
{
public:
virtual ~Derived2(void){}
};
namespace detail {
template <class T, class Tuple, std::size_t... I>
constexpr T make_from_tuple_impl( Tuple&& t, std::index_sequence<I...> )
{
return T(std::get<I>(std::forward<Tuple>(t))...);
}
template <class T, class Tuple>
constexpr T make_from_tuple( Tuple&& t )
{
return detail::make_from_tuple_impl<T>(std::forward<Tuple>(t),
std::make_index_sequence<std::tuple_size<std::decay_t<Tuple>>::value>{});
}
template<typename... Args>
struct DefferedConstruct {
std::tuple<Args&...> args_tuple;
template<typename T>
operator T*() {
return new T(make_from_tuple<T>(
args_tuple
));
}
};
} // namespace detail
template<typename... Args>
auto newObject(Args&&... args) -> detail::DefferedConstruct<Args...> {
return detail::DefferedConstruct<Args...>{
std::forward_as_tuple(args...)
};
}
int main()
{
// compiler picks the right newObject function according to the parameter type
Derived1 *p1 = newObject(1);
Derived2 *p2 = newObject();
delete p1;
delete p2;
}