std::将 std::unique_ptr 移动到 stl 容器中。 (MSVC 编译器问题)

Posted

技术标签:

【中文标题】std::将 std::unique_ptr 移动到 stl 容器中。 (MSVC 编译器问题)【英文标题】:std::move a std::unique_ptr into stl containers. (MSVC compiler issue) 【发布时间】:2013-05-02 01:54:49 【问题描述】:

MSVC 编译器存在一个已知错误,即未创建默认移动构造函数。

问题是我有很多类似于这样的类:

struct User 
    std::string FirstName;
    std::string LastName;
    std::string Address;
    std::string PostalCode;
    std::string City;

    std::vector<std::unique_ptr<ProjectBase>> Projects;
;

我如何学习这样的课程并将其转换为在这种情况下可以使用的东西:

std::vector<std::unique_ptr<User>> users;

    // I use this logic often (create a temporary object and move it into stl container
    auto new_user=make_unique<User>();
    users.push_back(std::move(new_a));

users.back()->FirstName="Should";
users.back()->LastName="Work";

std::cout << "First Name: " <<  users.back()->FirstName << std::endl;

上述代码在 Windows Phone 8 中不起作用(因为没有移动构造函数),但可以与 Visual Studio 2012 (v110) 工具包一起使用。

如果我的 User 类具有移动构造函数以便与 Windows Phone 8 一起使用,它会是什么样子?

【问题讨论】:

有什么原因你创建了一个变量表单make_unique 而不是仅仅做push_back(make_unique&lt;User&gt;()) 你试过User(User &amp;&amp;) = default;吗? @VaughnCato:MSVC 还不支持。 确实缺少最重要的功能之一。如果没有一大堆样板,你甚至无法定义最简单的类型,那么到底谁需要可变参数模板或 constexpr 之类的东西? VS 团队,下次请从容易实现的目标开始。 【参考方案1】:

只需调用std::move 即可为每个成员调用移动构造函数:

User(User&& u)
  : FirstName(std::move(u.FirstName)),
    LastName(std::move(u.LastName)),
    Address(std::move(u.Address)),
    PostalCode(std::move(u.PostalCode)),
    City(std::move(u.City)),
    Projects(std::move(u.Projects))

另外,要使用make_unique&lt;User&gt;();,您还需要一个用户定义的ctor,即User()

【讨论】:

我有 50 多个具有多个继承级别的类。有没有其他办法? @Grapes:您显示的代码需要移动 ctor。由于编译器不会为您生成一个,因此您必须明确定义一个。否则,您唯一的其他选择是避免任何需要移动 ctor 的代码。 @Grapes 这很乏味,但可能只需要几个小时。责备 VS 没有像他们应该的那样隐式生成它们。这让生活变得非常困难。请注意,如果您添加这些,请同时添加移动赋值运算符。

以上是关于std::将 std::unique_ptr 移动到 stl 容器中。 (MSVC 编译器问题)的主要内容,如果未能解决你的问题,请参考以下文章

将 const std::unique_ptr 用于 pimpl 习惯用法

使用 std::unique_ptr 的双向链表

将 std::unique_ptr 的子类与 std::variant 一起使用

如何将 std::sort() 与 std::unique_ptr<[]> 一起使用?

如何将 std::unique_ptr 初始化为引用

将 std::unique_ptr 类成员标记为 const