8

我有以下shared_ptr内容map

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

我想使用braced-init对其进行初始化。是否可以?

我试过了:

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

但是使用 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

我尝试了第一个参数(1000.0)的其他变体但没有成功。

任何人都可以帮忙吗?

4

5 回答 5

8

std::map有一个初始化列表构造函数:

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

我们可以很容易地使用这个构造函数创建一个地图:

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

要在 中使用它make_shared,我们需要指定initializer_list我们提供的实例化:

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

看起来真的很笨拙;但是如果你经常需要这个,你可以用别名来整理它:

#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}});

您可能更喜欢定义一个模板函数来包装调用:

#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}});
于 2016-04-06T08:55:48.233 回答
1

您的问题是您实际上没有在初始化程序中放置任何大括号。我需要以下内容才能使其正常工作:

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

双重std::map<double, std::string>困扰我。考虑到另一个,它确实应该能够解决其中一个……但是 gcc 5.3.0 不会打球。

你肯定需要双括号。(一旦说你正在初始化一个地图,一次是为了分隔每个条目。)

于 2016-04-06T08:55:46.853 回答
1

你可以不这样做std::make_shared

std::shared_ptr<std::map<double,std::string>> ptr(new std::map<double,std::string>({{1000.0, "string"}}));
于 2016-04-06T09:02:43.147 回答
-2

与此类似的东西应该这样做......

 std::string s1("temp");  

 std::map<double, std::string> *m = new std::map<double, std::string>{{100., s1}};

 auto foo = std::shared_ptr<std::map<double, std::string>>(m);

或作为单行者

auto foo2 = std::shared_ptr<std::map<double, std::string>>(new std::map<double, std::string>{{100., s1}});

(对不起,第一次错过了初始化列表的要求)

于 2016-04-06T08:43:30.547 回答
-4

更改密钥的类型。

double对于键来说是一种不好的类型,因为它没有operator==,并且不同的字节序列可以表示相同的浮点值。

于 2016-04-06T08:49:22.833 回答