Add an implicit conversion from unique_ptr <T> to T *
General question: Without going into a good idea, how can I add an implicit conversion operator to an already defined class? For example, let's say that I want unique_ptr <T> to implicitly convert to T * , but I cannot just add an element conversion operator, because I cannot change the definition of the unique_ptr class.
Options:
Is there some kind of C ++ voodoo that I can use to make this happen without creating a member function?
Answer-So-Far: NO.
There is no way to add an implicit conversion away from a type that you cannot change in the code.
Just ... sadness.Is it possible to get from std :: unique_ptr and add my own element conversion function? Are there any serious flaws in this?
Answer-So-Far: Yes (from vsoftco)
Deficiencies have not yet been determined. So far, inheriting from std :: unique_ptr, inheriting its constructors, and declaring the implicit conversion operator has worked fine, and hardly any code has been written.Will I just live without this for the rest of my life?
Answer-Yes-yes: we will see ...
If I can get option 2 and work without any serious side effects or loads, I will spend it for a while and let you know if it is considered worth it. We will see!
Code example:
#include <algorithm> #include <memory> #include <vector> struct MyClass { MyClass(int v) : value(v) {} int value; }; int main() { auto vec = std::vector<std::unique_ptr<MyClass>>(); vec.push_back(std::make_unique<MyClass>(1)); vec.push_back(std::make_unique<MyClass>(2)); // error C2664: 'void (__vectorcall *)(MyClass *)' : cannot convert argument 1 from 'std::unique_ptr<MyClass,std::default_delete<_Ty>>' to 'MyClass *' std::for_each(std::begin(vec), std::end(vec), [](MyClass* myClass) { myClass->value += 3; }); } If you do not want to use the std::unique_ptr<>::get() function, you can:
Define a free function that takes
std::unique_ptrand returns the raw pointer returned byget, although I don't think it really makes your code better, for example:// free function template<typename T> T* get_raw_ptr(const std::unique_ptr<T>& up) { return up.get(); }The conversions of
unique_ptrto source pointers are fine, but they must be explicit. Implicit conversion can lead to many headaches, as they can happen when you least expect them.A bad idea consists of
std::unique_ptr, since the latter is not used as a base class (it does not have a virtual destructor). In general, the bad of the standard library classes. However, if you really insist, you can use a wrapper in which you define an implicit conversion operator, for example:// wrapper template <class T, class Deleter = std::default_delete<T>> class unique_ptr_wrapper: public std::unique_ptr<T, Deleter> { public: using std::unique_ptr<T, Deleter>::unique_ptr; // inheriting base ctors operator T* () const {return this->get();} };
and use just looks like
// wrapper usage: unique_ptr_wrapper<int> upw{new int{42}}; int* p = upw; // implicit conversion OK - 1 and 2 can help you, so you can improve your life;)