【问题标题】:Initialize a const map which has shared_ptr as values初始化一个以 shared_ptr 作为值的 const 映射
【发布时间】:2013-02-13 22:38:21
【问题描述】:

我正在尝试创建一个 const 映射,其键为 int,第二个值是 shared_ptr 到一个类。

假设我有一个类 A 和 B,而 C 派生自 A。 我希望能够创建地图

const map<int, shared_ptr<A>> mymap

并使用值初始化地图:

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

但是使用初始化列表会出错。 关于如何执行此操作的任何帮助?

【问题讨论】:

  • 请附上您遇到的错误、您使用的编译器,或许还有一个完整的小程序来说明您所做的事情。

标签: c++ c++11 shared-ptr


【解决方案1】:

问题是您试图从原始指针隐式构造shared_ptr。您必须以这种方式初始化地图:

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

C++11 标准的第 20.7.2.2 段要求 shared_ptr&lt;&gt; 的构造函数接受原始指针为 explicit

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

问题是您试图通过将原始指针作为第二个参数传递给pair&lt;&gt; 的构造函数来构造std::pair&lt;int, shared_ptr&lt;A&gt;&gt; 的实例,该构造函数接受shared_ptr&lt;A&gt;。基本上,这与:

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

这就是说,除非你有很好的理由不这样做并且你真的知道你在做什么,否则最好使用std::make_shared&lt;&gt;() 创建共享指针,这都是因为效率(它执行一次内存分配而不是二)和异常安全(如果BC的构造函数抛出异常,它不会泄漏)。因此,您的地图初始化应如下所示:

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

【讨论】:

  • 使用 std::make_shared 可能会更好。
  • @Shiroko:确实。我只是想说明问题的本质。将其添加到我的答案中。
猜你喜欢
  • 2011-05-22
  • 1970-01-01
  • 2011-02-07
  • 2011-04-02
  • 1970-01-01
  • 2014-01-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多