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; }); } 
+6
source share
1 answer

If you do not want to use the std::unique_ptr<>::get() function, you can:

  • Define a free function that takes std::unique_ptr and returns the raw pointer returned by get , 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_ptr to 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. 1 and 2 can help you, so you can improve your life;)
+4
source

Source: https://habr.com/ru/post/988249/


All Articles