Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Initialize a const map which has shared_ptr as values

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

Let say, I have a class A with B, and C derived from A. I want to be able to create a map

const map<int, shared_ptr<A>> mymap

and initialize the map with the values:

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

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

like image 908
Saket Jalan Avatar asked Aug 04 '26 13:08

Saket Jalan


1 Answers

The problem is that you are trying to construct a shared_ptr implicitly from a raw pointer. You have to initialize your map this way:

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

Paragraph 20.7.2.2 of the C++11 Standard demands shared_ptr<>'s constructor that accept a raw pointer to be explicit:

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

The problem is that you are trying to construct instances of std::pair<int, shared_ptr<A>> by passing a raw pointer as the second argument to the pair<>'s constructor, which accepts a 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 said, unless you have very good reasons to do otherwise 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 performs one memory allocation instead of two) and exception-safety (it won't leak if the constructor of B or C throws an exception). Thus, your map initialization should look like:

const map<int, shared_ptr<A>> mymap = {
    {1, make_shared<B>()}, 
    {2, make_shared<C>()}
    };
like image 127
Andy Prowl Avatar answered Aug 07 '26 02:08

Andy Prowl



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!