2013-05-05 3 views
7

다음 코드는 C++ 11에 따라 컴파일 오류를 생성합니까? (그렇다면 왜?) 또는 VC11에 문제가 있습니까? 비주얼 C++ 2012unique_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; }); 
} 

는 다음과 같은 컴파일 오류가 발생합니다 :

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

그것은 비주얼 C에 문제가 있었다 ++ 2012 (연결에 마이크로 소프트에 의해 인정 : Compile error in C++ code sorting a list of objects holding a vector of unique_ptr를)하고 이미 또한 ++ 2013

, 내가 문제가 있음을 지적하고 싶습니다 비주얼 C 수정되었습니다 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에 문제"하지만 당신은 비주얼 스튜디오를 오용하는 경우에만 때문이다.

VC++는 r 값 참조를 구현하지만 은 아니며은 컴파일러에서 생성 한 이동 생성자/할당 연산자를 구현합니다. 즉, 유형을 이동 가능하게하려면 직접 작성해야합니다.

A은 이동식이 아니므로 다양한 std::list 함수가이를 복사하려고 시도합니다. 그리고 vector (unique_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 소스 코드에서 답을 찾을 수 있습니다. 나는 너의 요점을 이해한다. –

관련 문제