2013-05-05 12 views
7

C++ 11によるコンパイルエラーが発生するのはなぜですか(なぜですか?)、またはVC11に問題がありますか?unique_ptrのベクトルを保持するオブジェクトのリストを並べ替え

#include <vector> 
#include <list> 
#include <memory> 
struct A 
{ 
    std::vector<std::unique_ptr<int>> v; 
}; 
int main() 
{ 
    std::list<A> l; 
    l.sort([](const A& a1, const A& a2){ return true; }); 
} 

のVisual C++ 2012は、次のコンパイルエラーを生成します。

1>c:\program files (x86)\microsoft visual studio 11.0\vc\include\xmemory0(606): error C2248: 'std::unique_ptr<_Ty>::unique_ptr' : cannot access private member declared in class 'std::unique_ptr<_Ty>' 
1>   with 
1>   [ 
1>    _Ty=int 
1>   ] 
1>   c:\program files (x86)\microsoft visual studio 11.0\vc\include\memory(1447) : see declaration of 'std::unique_ptr<_Ty>::unique_ptr' 
1>   with 
1>   [ 
1>    _Ty=int 
1>   ] 
1>   c:\program files (x86)\microsoft visual studio 11.0\vc\include\xmemory0(605) : while compiling class template member function 'void std::allocator<_Ty>::construct(_Ty *,const _Ty &)' 
1>   with 
1>   [ 
1>    _Ty=std::unique_ptr<int> 
1>   ] 
1>   c:\program files (x86)\microsoft visual studio 11.0\vc\include\xmemory0(751) : see reference to function template instantiation 'void std::allocator<_Ty>::construct(_Ty *,const _Ty &)' being compiled 
1>   with 
1>   [ 
1>    _Ty=std::unique_ptr<int> 
1>   ] 
1>   c:\program files (x86)\microsoft visual studio 11.0\vc\include\type_traits(743) : see reference to class template instantiation 'std::allocator<_Ty>' being compiled 
1>   with 
1>   [ 
1>    _Ty=std::unique_ptr<int> 
1>   ] 
1>   c:\program files (x86)\microsoft visual studio 11.0\vc\include\vector(655) : see reference to class template instantiation 'std::is_empty<_Ty>' being compiled 
1>   with 
1>   [ 
1>    _Ty=std::allocator<std::unique_ptr<int>> 
1>   ] 
1>   d:\test2\test2.cpp(213) : see reference to class template instantiation 'std::vector<_Ty>' being compiled 
1>   with 
1>   [ 
1>    _Ty=std::unique_ptr<int> 
1>   ] 
+0

参考までに、これはClangとGCCでうまくコンパイルできます。だからあなたのコンパイラか設定のどちらかです。 – chrisaycock

+0

@chrisaycockああ、Microsoft Connectでさらに別のVC11バグレポートを作成しようとしています... – PowerGamer

+3

私はむしろそれをすべて放棄したいと思います。 –

答えて

0

それは(接続にMicrosoftによって承認:Compile error in C++ code sorting a list of objects holding a vector of unique_ptr)のVisual C++ 2012での問題であり、それはすでにのVisual C++また、2013年

に固定して、私は問題があることを指摘したいと思いますVisual C++は暗黙的に移動コンストラクタを生成しないという事実とは関係がありませんでした。明示的に構造体Aのすべてのコピーと移動のコンストラクタを削除した場合(元の例では、タイプAのオブジェクトをリストに挿入することは不可能ですが、それはポイントの横にあります)、コードはまだコピーや移動を行わないコンパイルエラーが発生します。

#include <vector> 
#include <list> 
#include <memory> 
struct A 
{ 
    std::vector<std::unique_ptr<int>> v; 
    A(A&&) = delete; 
    A(const A&) = delete; 
}; 
int main() 
{ 
    std::list<A> l; 
    l.sort([](const A& a1, const A& a2){ return true; }); 
} 
4

それは、 "VCでの問題" ですが、Visual Studioを悪用しているという理由だけで。

VC++はr値参照を実装しますが、ではありません。では、コンパイラ生成の移動コンストラクタ/代入演算子を実装しています。つまり、タイプを移動可能にしたい場合は、自分でタイプする必要があります。

Aは可動型ではないため、さまざまなstd::list関数がそれらをコピーしようとします。 vectorunique_ptr)をコピーしようとすると失敗します。したがって、コンパイラのエラーです。

VC++で移動対応オブジェクトを使用する場合は、移動コンストラクタ/割り当てを自分で記述する必要があります。

+2

リストをソートすると(ベクターではない)何かのコピーが必要なのはなぜですか?ソートは二重リンクリストノードの "前"と "次"ポインタを変更することで実装されるはずですか? – PowerGamer

3

問題は実際にはVC11で、it doesn't implement C++11 feature of automatically generating move operations(既にNicol Bolasに釘付けされているように)です。

次のコードはVC10 SP1でコンパイルされます。このコードサンプルでは、​​ムーブコンストラクタはと明示的にと書かれています(移動の代わりに、copy-and-swap idiomが使用されます)。

#include <algorithm> // for std::swap (for copy-and-swap idiom) 
#include <list> 
#include <memory> 
#include <vector> 

struct A 
{ 
    std::vector<std::unique_ptr<int>> v; 

    A(A&& other) 
     : v(std::move(other.v)) 
    { 
    } 

    A& operator=(A other) 
    { 
     swap(*this, other); 
     return *this; 
    } 

    friend void swap(A& lhs, A& rhs) 
    { 
     using std::swap; 
     swap(lhs.v, rhs.v); 
    } 
}; 

int main() 
{ 
    std::list<A> l; 
    l.sort([](const A& , const A&){ return true; }); 
} 
+1

私は動きのコンストラクタが何であるか、そしてVC11がそれらを暗黙的に生成しないという事実をよく知っています。これはVC11が* list *のソートを実行しているときに、タイプAのオブジェクトをコピーまたは移動させたいのはほんの少ししか説明していません。 – PowerGamer

+0

さて、あなたはSTLのソースコードで答えを見つけることができます。私はあなたのことを理解しています。 –

関連する問題