简体   繁体   English

被矢量击败<unique_ptr>

[英]Defeated by vector<unique_ptr>

Coming back to C++ after many years; 多年后回到C ++; trying to catch up to C++11 & 14. I've read about rvalues and move semantics. 试图赶上C ++ 11和14.我已经阅读了关于rvalues和移动语义的内容。 I thought I understood the concept. 我以为我理解了这个概念。 Apparently not. 显然不是。 I've looked at dozens of examples. 我看过几十个例子。 But I simply can't get my code to compile. 但我根本无法编译我的代码。 I must be missing something obvious in the examples. 我必须遗漏一些明显的例子。 I always get the error about the copy ctor being deleted because of unique_ptr<int> having a user-declared move ctor. 我总是得到关于copy ctor被删除的错误,因为unique_ptr<int>有一个用户声明的移动ctor。 There's obviously something I'm missing about the concept, but I can't figure out what it is. 显然我对这个概念缺少了一些东西,但我无法弄清楚它是什么。 Here's the code, stripped down to its essence: 这是代码,根据其本质:

#include <memory>
#include <utility>
#include <vector>

int main(int, char*[]) {
  auto oneInt{std::make_unique<int>(0)};
  auto someInts{std::vector<std::unique_ptr<int>>{std::move(oneInt)}};

  return 0;
}

What am I doing wrong? 我究竟做错了什么?

Edit: Here's the error from this particular code. 编辑:这是这个特定代码的错误。 Note that I've tried every variation on the code that I can think of, with varying results, but the basic problem is always the same: copy ctor deleted because unique_ptr<int> has a user-declared move ctor. 请注意,我已经尝试了我能想到的代码的每个变体,结果各不相同,但基本问题始终是相同的:复制ctor已删除,因为unique_ptr<int>具有用户声明的移动ctor。

Edit: I've updated the code to #include <memory> , and pasted the new error. 编辑:我已将代码更新为#include <memory> ,并粘贴了新错误。 I can only wish the problem were something silly like that. 我只能希望问题是那样的傻事。

    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/memory:1752:31: error: call to implicitly-deleted copy constructor of
      'std::__1::unique_ptr<int, std::__1::default_delete<int> >'
            ::new((void*)__p) _Up(_VSTD::forward<_Args>(__args)...);
                              ^   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/memory:1668:18: note: in instantiation of function template
      specialization 'std::__1::allocator<std::__1::unique_ptr<int, std::__1::default_delete<int> > >::construct<std::__1::unique_ptr<int, std::__1::default_delete<int> >,
      const std::__1::unique_ptr<int, std::__1::default_delete<int> > &>' requested here
            {__a.construct(__p, _VSTD::forward<_Args>(__args)...);}
                 ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/memory:1514:14: note: in instantiation of function template
      specialization 'std::__1::allocator_traits<std::__1::allocator<std::__1::unique_ptr<int, std::__1::default_delete<int> > > >::__construct<std::__1::unique_ptr<int,
      std::__1::default_delete<int> >, const std::__1::unique_ptr<int, std::__1::default_delete<int> > &>' requested here
            {__construct(__has_construct<allocator_type, _Tp*, _Args...>(),
             ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/memory:1598:17: note: in instantiation of function template
      specialization 'std::__1::allocator_traits<std::__1::allocator<std::__1::unique_ptr<int, std::__1::default_delete<int> > > >::construct<std::__1::unique_ptr<int,
      std::__1::default_delete<int> >, const std::__1::unique_ptr<int, std::__1::default_delete<int> > &>' requested here
                construct(__a, _VSTD::__to_raw_pointer(__begin2), *__begin1);
                ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/vector:1024:21: note: in instantiation of function template
      specialization 'std::__1::allocator_traits<std::__1::allocator<std::__1::unique_ptr<int, std::__1::default_delete<int> > > >::__construct_range_forward<const
      std::__1::unique_ptr<int, std::__1::default_delete<int> > *, std::__1::unique_ptr<int, std::__1::default_delete<int> > *>' requested here
    __alloc_traits::__construct_range_forward(__a, __first, __last, this->__end_);
                    ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/vector:1285:9: note: in instantiation of function template
      specialization 'std::__1::vector<std::__1::unique_ptr<int, std::__1::default_delete<int> >, std::__1::allocator<std::__1::unique_ptr<int, std::__1::default_delete<int> >
      > >::__construct_at_end<const std::__1::unique_ptr<int, std::__1::default_delete<int> > *>' requested here
        __construct_at_end(__il.begin(), __il.end(), __il.size());
        ^
virtual.cpp:7:21: note: in instantiation of member function 'std::__1::vector<std::__1::unique_ptr<int, std::__1::default_delete<int> >,
      std::__1::allocator<std::__1::unique_ptr<int, std::__1::default_delete<int> > > >::vector' requested here
      auto someInts{std::vector<std::unique_ptr<int>>{std::move(oneInt)}};
                    ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/memory:2621:31: note: copy constructor is implicitly deleted because
      'unique_ptr<int, std::__1::default_delete<int> >' has a user-declared move constructor
    _LIBCPP_INLINE_VISIBILITY unique_ptr(unique_ptr&& __u) _NOEXCEPT

There are a lot of problems with your code. 您的代码存在很多问题。 First, there is an excessive use of {} initialization that confuses things. 首先,过度使用{}初始化会混淆事物。 Using auto is fine, but auto x{...}; 使用auto很好,但是auto x{...}; declarations are fraught with peril, as the meaning of auto x{single_value} has shifted over time. 声明充满了危险,因为auto x{single_value}的含义随着时间的推移而变化。 It's best to use auto x = single_value; 最好使用auto x = single_value; syntax where reasonable. 语法哪里合理。

Second, you cannot insert a unique_ptr into a container through a {} initializer list. 其次,您不能通过{}初始化列表将unique_ptr插入到容器中。 At all. 完全没有。 Items that go through std::initializer_list must be copyable, and unique_ptr is not. 通过std::initializer_list 必须是可复制的,而unique_ptr则不是。

What you want is this: 你想要的是这个:

auto oneInt = std::make_unique<int>(0);
std::vector<std::unique_ptr<int>> someInts;
someInts.push_back(std::move(oneInt));

The short answer is that a std::initializer_list contains values; 简短的回答是std::initializer_list包含值; and they cannot be moved out of, only copied from. 并且它们不能被移出,只能从中复制出来。 To be clear, if you use the initializer_list form of construction for a vector , the items in the list are copied into the vector. 需要明确的是,如果对vector使用initializer_list构造形式,则列表中的项目将复制到向量中。

See this thread for discussion of your exact problem and some suggested workarounds. 请参阅此主题以讨论您的确切问题和一些建议的解决方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM