Insert std :: unique_ptr into boost: ptr_map

I'm moving the old code to C ++ 14, it used the deprecated auto_ptr and worked well with boost: ptr_map, you could do:

auto_ptr<Foo> foo(new Foo);
boost:map_ptr<int, Foo> m;
m.insert(5, foo);

      

Now, by replacing auto_ptr with unique_ptr, it doesn't compile:

unique_ptr<Foo> foo(new Foo);
boost:map_ptr<int, Foo> m;
m.insert(5, foo);            // Does not compile
m.insert(5, move(foo));      // Does not compile either,
                             // this should be the right thing to do
m.insert(5, move.release()); // Does compile, but isn't exception safe

      

API map_ptr not updated yet?

Edit based on answers using unique_ptr map is not a good option in my case because it requires quite a lot of code rewriting to do so. I really wanted it to work with map_ptr, I am dealing with some old code and I want to make minimal changes.

+3


source to share


3 answers


I think in C ++ 14 you want:

std::unordered_map<int, std::unique_ptr<Foo>> x;
x.emplace(5, std::make_unique<Foo>());

      



You don't need those old _ptr booster containers anymore, they were mostly workarounds due to the lack of a null overhead owning pointer that can be safely handled in containers (i.e. unique_ptr

).

+3


source


you can use

std::unordered_map<int, std::unique_ptr<Foo>> x;
x.emplace(5, std::make_unique<Foo>());

      



Its a C ++ 14 feature. No need for old injectors! :)

+2


source


API map_ptr not updated yet?

No, you're just using it wrong.

As from the documentation :

Ptr_map is a pointer container that uses the underlying std :: map to store pointers.

Please note that this will not compile:

unique_ptr<Foo> foo(new Foo);
void *ptr = foo;

      

Since you can't convert std::unique_ptr

to void *

with assignment, it doesn't make much sense.
This is more or less what happens internally when you try to do this:

m.insert(5, move(foo));

      

On the other hand, it compiles instead:

unique_ptr<Foo> foo(new Foo);
Foo *bar = foo.realease();
void *ptr = bar;

      

Something close to:

m.insert(5, move.release());

      

Therefore, you cannot expect the first case to work, and in fact it does not.


I currently prefer to use the int map std::unique_ptr<Foo>

from both the standard template library and get rid of boost::ptr_map

, as suggested in the comments to the question.
Something like the following should work:

std::map<int, std::unique_ptr<Foo>>

      

Note that a is std::map

more appropriate than std::unordered_map

if you need something closer to how it works boost::ptr_map

, as above, its underlying data structure is this std::map

, not std::unordered_map

.

0


source







All Articles