【问题标题】:using an initializer list where the values contain unique_ptr member variables [duplicate]使用值包含 unique_ptr 成员变量的初始值设定项列表 [重复]
【发布时间】:2021-11-19 14:59:10
【问题描述】:

我有一个包含 unique_ptr 的类。我想将此类的实例放在容器中(特别是 std::map)。这使用std::move.emplace 有效,但是,我想在容器的初始化程序列表中执行所有这些初始化。这可能吗?

我怀疑Foo 在初始化列表中被初始化,然后被复制,这导致了问题。我试过在初始化列表中添加一个std::move,但这并没有解决问题。

class Foo
{
public:
  std::unique_ptr<std::string> my_str_ptrs;
}

编译失败“试图访问已删除的函数”。 这是我想做的一个例子

std::map<std::string, Foo> my_map{
  {"a", Foo{}}
};

编译成功

std::map<std::string, Foo> my_map;
my_map.emplace("a", Foo{});

【问题讨论】:

  • std::unique_ptr&lt;std::string&gt; my_str_ptrs; 更改为std::vector&lt;std::string&gt; my_strs
  • 如何为class Foo 编写一个复制构造函数,它将按照您的意图执行来自Foo{} 的复制。对于std::unique_ptr,您可以使用克隆来正确执行复制。
  • @KarenBaghdasaryan,我试过这个,但得到了相同的结果。根据 kaldrr 的回答,除非我更改 std::initializer_list 代码,否则我认为没有任何方法可以完成这项工作。
  • @J'e 我认为只要绑定到 const lvalue ref,就可以克隆 my_str_ptrs 的内容,并且复制的变量应该有一个 std::unique_ptr给它。

标签: c++ unique-ptr initializer-list stdmove


【解决方案1】:

这是std::initializer_list的错,如果你看它的begin/end成员函数,它们返回const T*,这意味着它会强制std::map尝试使用你的Foo的复制构造函数,即deleted,因为std::unique_ptr无法复制。

这个问题不是std::map 独有的,任何允许您使用std::initializer_list 对其进行初始化的容器都会真正从初始化列表中复制参数。

C++ 标准要求在此类初始化期间有一个临时的 const T[N] 数组,std::initializer_list 指向该数组,const 禁止从它移动。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-09-15
    • 1970-01-01
    • 1970-01-01
    • 2018-12-18
    • 1970-01-01
    • 1970-01-01
    • 2015-08-23
    相关资源
    最近更新 更多