Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Initialising std::shared_ptr<std::map<>> using braced-init

I have the following shared_ptr to a map:

std::shared_ptr<std::map<double, std::string>>

and I would like to initialise it using braced-init. Is it possible?

I've tried:

std::string s1("temp");
std::shared_ptr<std::map<double, std::string>> foo = std::make_shared<std::map<double, std::string>>(1000.0, s1);

but that gives the following error when compiled using Xcode 6.3:

/usr/include/c++/v1/map:853:14: Candidate constructor not viable: no known conversion from 'double' to 'const key_compare' (aka 'const std::__1::less<double>') for 1st argument

I've tried other variations of the first parameter (1000.0) without success.

Can anyone help?

like image 571
ksl Avatar asked Apr 06 '16 08:04

ksl


1 Answers

std::map has an initializer-list constructor:

map (initializer_list<value_type> il,
     const key_compare& comp = key_compare(),
     const allocator_type& alloc = allocator_type());

We can create a map using this constructor quite easily:

std::map<double,std::string> m1{{1000.0, s1}};

To use it in make_shared, we need to specify which instantiation of initializer_list we're providing:

auto foo = std::make_shared<std::map<double,std::string>>
           (std::initializer_list<std::map<double,std::string>::value_type>{{1000.0, s1}});

That looks really clumsy; but if you need this regularly, you could tidy it up with aliases:

#include <string>
#include <map>
#include <memory>

std::string s1{"temp"};

using map_ds = std::map<double,std::string>;
using il_ds = std::initializer_list<map_ds::value_type>;

auto foo = std::make_shared<map_ds>(il_ds{{1000.0, s1}});

You might instead prefer to define a template function to wrap the call:

#include <string>
#include <map>
#include <memory>

template<class Key, class T>
std::shared_ptr<std::map<Key,T>>
make_shared_map(std::initializer_list<typename std::map<Key,T>::value_type> il)
{
    return std::make_shared<std::map<Key,T>>(il);
}

std::string s1{"temp"};
auto foo = make_shared_map<double,std::string>({{1000, s1}});
like image 65
Toby Speight Avatar answered Oct 19 '22 20:10

Toby Speight