#include <type_traits>
#include <utility>

template< typename T >
class clone_ptr_polymorph
{
    void* mDerivedPtr;
    T* mBasicPtr;
    std::pair<T*, void*> (* mCloner)(void*);  

    template< typename Derived >
    static std::pair<T*, void*> clone(void* ptr)
    {
    	auto obj = new Derived{ *reinterpret_cast<Derived*>(ptr) };
    	return { obj, obj };
    }
    
public:
    template< typename Derived,
              typename=typename std::enable_if<std::is_base_of<T, Derived>::value>::type >
    clone_ptr_polymorph( Derived* ptr ) :
        mDerivedPtr{ptr},
        mBasicPtr{ptr},
        mCloner{ &clone<Derived> } {}
        
    clone_ptr_polymorph( clone_ptr_polymorph const& p ) :
        mCloner{p.mCloner}
    {
    	auto pair = mCloner(p.mDerivedPtr);
    	mBasicPtr = pair.first;
    	mDerivedPtr = pair.second;
    }
    
    ~clone_ptr_polymorph()
    {
    	delete mBasicPtr;
    }
    
    clone_ptr_polymorph( clone_ptr_polymorph&& ) = default;
    clone_ptr_polymorph& operator=( clone_ptr_polymorph&& ) = default;
};
    
template<typename Base,
         typename Der,
         typename... Args>
clone_ptr_polymorph<Base> make_clone_ptr( Args&&... args )
{
	return { new Der(std::forward<Args>(args)...) };
}

#include <iostream>

struct Base
{
	virtual ~Base() { std::cout << "Base-Destructor\n"; }
	Base() { std::cout << "Base-Def-Ctor\n"; }
	Base(Base const&) { std::cout << "Base-Copy-Ctor\n"; }
	Base(Base&&) { std::cout << "Base-Move-Ctor\n"; }
};

struct Derived : Base
{
	~Derived() { std::cout << "Derived-Destructor\n"; }
	Derived() { std::cout << "Derived-Def-Ctor\n"; }
	Derived(Derived const&) { std::cout << "Derived-Copy-Ctor\n"; }
	Derived(Derived&&) { std::cout << "Derived-Move-Ctor\n"; }
};

int main()
{
	auto const& p = make_clone_ptr<Base, Derived>();
	auto second = p;
}

    