Initialize a const map that has shared_ptr as values

I am trying to create a const map with the key as int and the second value is a shared_ptr for the class.

Let's say I have a class A with B and C is derived from A. I want to create a map

const map<int, shared_ptr<A>> mymap

      

and initialize the map with values:

{1, new B()} and {2, new C()}

      

But using an initializer list gives an error. Any help on how I can do this?

+3


source to share


1 answer


The problem is that you are trying to construct shared_ptr

implicitly from a raw pointer. You have to initialize your map like this:

const map<int, shared_ptr<A>> mymap = {
    {1, shared_ptr<B>(new B())}, 
    {2, shared_ptr<C>(new C())}
    };

      

Clause 20.7.2.2 of the C ++ 11 standard requires a constructor shared_ptr<>

that takes a raw pointer explicit

:

template<typename Y> explicit shared_ptr(Y* p);

      



The problem is when you are trying to construct instances std::pair<int, shared_ptr<A>>

by passing a raw pointer as the second argument to the constructor pair<>

that it takes shared_ptr<A>

. Basically, this is the same as:

pair<int, shared_ptr<A>> mymap(1, new B()); // ERROR!
pair<int, shared_ptr<A>> mymap(1, shared_ptr<B>(new B())); // OK

      

This goes to show that unless you have a compelling reason to do this and you really know what you are doing, it is always better to use std::make_shared<>()

to create shared pointers, both because of efficiency (it does one memory allocation instead of two) and exception-safety (it won't leak if constructor B

or C

throws an exception). So your map initialization should look like this:

const map<int, shared_ptr<A>> mymap = {
    {1, make_shared<B>()}, 
    {2, make_shared<C>()}
    };

      

+7


source







All Articles