2017-08-27 14 views
2

長年の後にC++に戻る; C++ 11に追いつこうとしています& 14.私はrvaluesとmove semanticsについて読んだことがあります。私はそのコンセプトを理解していると思った。どうやらない。私は数十の例を見てきました。しかし、私は自分のコードをコンパイルすることはできません。私は例で明白な何かを見逃すはずです。私はいつも、ユーザーが宣言した移動コードを持つunique_ptr<int>のために、削除されているコピーctorに関するエラーを受け取ります。明らかに、私がこのコンセプトについて見逃していることはありますが、私はそれが何であるか把握できません。ベクトルによって敗北<unique_ptr>

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

私は間違って何をしていますか?

編集:ここは、この特定のコードのエラーです。さまざまな結果を考えて、私は考えることができるすべてのバリエーションを試しましたが、基本的な問題は常に同じです:unique_ptr<int>にはユーザーが宣言した移動コードがあるため、コピーctorが削除されました。

編集:コードを#include <memory>に更新し、新しいエラーを貼り付けました。私はその問題がそんなに愚かなことだったら嬉しいです。

/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 
+4

。あなたの質問を編集して、ビルドからの完全で完全な修正されていない出力をテキストとして含めることができます。 –

+4

」ヘッダーは含まれていませんでした。 – StoryTeller

+2

'oneInt'は初期化子リストに移動されますが、コピーされます。 – molbdnilo

答えて

6

コードには多くの問題があります。まず、事を混乱させるような初期設定の{}の過剰使用があります。 autoを使用しても問題ありませんが、auto x{single_value}の意味が時間とともに変化しているため、auto x{...};の宣言は危険に満ちています。妥当な場合は、auto x = single_value;の構文を使用することをお勧めします。

第2に、{}イニシャライザリストを使用してunique_ptrをコンテナに挿入することはできません。まったく。 std::initializer_listを通過するアイテムは、コピー可能ででなければならず、unique_ptrはコピー可能でなければなりません。

何がしたいことはこれです:それは通常のエラーを見て助けビルドエラーについて尋ねたとき

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

* std :: initializer_listを通過するアイテムはコピー可能でなければなりません。 – GreatBigBore

+0

'someInts.push_back(std :: move(oneInt))'が正しいことであるかどうかわかりません。最初の 'move'の後に' oneInt'の内部になるのは何ですか?何もない! –

+1

@SemyonBurov:良いアイデアでもなくても、OPが提供したコードの意図と一致します。 –

2

短い答えは、std::initializer_listに値が含まれていることです。それらはコピーされただけで移動できません。明確にするには、vectorのinitializer_list形式を使用すると、リスト内の項目がベクターにコピーされます。

See this threadあなたの正確な問題といくつかの推奨される回避策についての説明は、

関連する問題