Regardless of the fact that copying a unique_ptr
makes sense or not*, I tried to implement this kind of class, simply wrapping a std::unique_ptr
, and got into difficulty exactly where the copy is taken, in the case of a smart pointer to base and the stored object being a derived class.
A naive implementation of the copy constructor can be found all over the internet (data
is the wrapped std::unique_ptr
):
copyable_unique_ptr::copyable_unique_ptr(const copyable_unique_ptr& other)
: data(std::make_unique(*other.get()) // invoke the class's copy constructor
{}
Problem here is, that due to the left out template arguments, is that the copy creates an instance of the type T
, even if the real type is U : T
. This leads to loss of information on a copy, and although I understand perfectly well why this happens here, I can't find a way around this.
Note that in the move case, there is no problem. The original pointer was created properly somewhere in user code, and moving it to a new owner doesn't modify the object's real type. To make a copy, you need more information.
Also note that a solution employing a clone
function (thus infecting the type T
's interface) is not what I would find to be acceptable.
*if you want a single owning pointer to a copyable resource this can make sense and it provides much more than what a scoped_ptr
or auto_ptr
would provide.
After some struggling with getting all the magic incantations right so that a good C++ compiler is satisfied with the code, and I was satisfied with the semantics, I present to you, a (very barebones)
value_ptr
, with both copy and move semantics. Important to remember is to usemake_value<Derived>
so it picks up the correct copy function, otherwise a copy will slice your object. I did not find an implementation of adeep_copy_ptr
orvalue_ptr
that actually had a mechanism to withstand slicing. This is a rough-edged implementation that misses things like the fine-grained reference handling or array specialization, but here it is nonetheless:Code lives here and tests to show how it should work are here for everyone to see for themselves. Comments always welcome.