2016-09-01 3 views
7

> (서로 다른 경우) : 나는 복사 벡터 <shared_pt<T>> 나는이 C++

std::vector<std::shared_ptr<const T>> 

에 복사하고 싶은

std::vector<std::shared_ptr<T>> 

지금 나는 것으로 나타났습니다 경우 I 이 작업을 수행 : 그것은 잘 컴파일

class A 
{ 
public: 
    A(const std::vector<std::shared_ptr<int>>& list) : internalList(list.begin(), list.end()) {} 
    std::vector<std::shared_ptr<const int>> internalList; 
}; 

(연타 ++ 표준을 == C++ 14)하지만 내가 할 경우 :

class A 
{ 
public: 
    A(const std::vector<std::shared_ptr<int>>& list) : internalList(list) {} 
    std::vector<std::shared_ptr<const int>> internalList; 
}; 

복사 생성자를 사용할 때 non-const에서 const 로의 변환을 알아낼 수 없기 때문에 복사 생성자를 사용할 때 이상하다는 것을 알았습니까?

xxxx.cpp:672:56: error: no matching constructor for initialization of 'std::vector<std::shared_ptr<const int> >' 

사람은 왜하시기 바랍니다 설명 할 수 있고, 나는 그것이 (생성자에서 반복자를 사용) 할 방법이 최선의 해결책 인 경우?

std::vector가 변환 생성자를 제공하는 경우 코드가 작동 할 수
+1

비 const에서 const 로의 변환 (즉, int int에서 const int 로의 변환)이면 괜찮습니다. 그러나 그것은 여기서 일어나는 것이 아닙니다. 한 유형의 객체에서 완전히 다른 유형의 객체로의 변환입니다. 복사 생성자는 다른 유형이 아닌 인수로만 자체 유형을 취합니다. –

+0

좋아요,하지만이 작품과 같은 것이 아닙니다. 'int a = 1; const int b = a'? 그래서 내 질문에 왜이 할당 작동하고 왜 복사 생성자를 사용하여 수행 할 수 없습니다? 이 일을 막는 것이 무엇인지 정말 궁금합니다. 최적화를 위해 완료되지 않았다고 가정합니다 ... – user18490

+1

@ user18490'const std :: vector '은'std :: vector '과 같지 않습니다. 그러므로'int'와'const int'는 유추가되지 않습니다. –

답변

2

처음에는 다른 유형으로 인스턴스화 된 클래스 템플릿은 완전히 다른 유형입니다. std::shared_ptr<int>std::shared_ptr<const int>은 전혀 다른 유형이며 std::vector<std::shared_ptr<int>>std::vector<std::shared_ptr<const int>>도 서로 다른 유형이므로 서로 변환 할 수 없습니다.

에 따르면 복사 생성자 (다섯 번째 것)는 해당 매개 변수와 동일한 유형의 std::vector을 사용합니다. std::vector<std::shared_ptr<const int>>의 경우 std::vector<std::shared_ptr<int>>을 사용할 수 없으며 암시 적으로 std::vector<std::shared_ptr<const int>>으로 변환 할 수 없습니다.

반대로 반복자 범위 (네 번째 매개 변수)를 취하는 생성자는 함수 템플릿이며 반복자의 유형은 템플릿 매개 변수이며 동일한 유형을 가리키는 반복자 일 필요는 없습니다. 이 유형이 벡터를 구성하는 데 사용될 수 있다면 다른 유형을 가리키는 반복자가 될 수 있습니다. std::shared_ptr<const int>을 생성하려면 std::shared_ptr<int>을 사용할 수 있습니다.

std::shared_ptr에는 다른 요소 유형을 인수로 사용하여 std::shared_ptr을 취할 수있는 복사/이동 생성자 템플릿이 있습니다. (std::vector은 그렇지 않습니다.)

3

:

template<class T, class A = std::allocator<T>> 
class vector { 
public: 
    template<class T1, class A1> 
    explicit vector(const vector<T1, A1>& other) 
     : vector(other.begin(), other.end()) 
    {} 

    ... 
}; 

그러나 거의 같은 효과를 도입하여 달성 할 수 있기 때문에, 너무 많은 값을 추가하지 않습니다 모든 표준 라이브러리 컨테이너 등의 생성자를 가진 보다 일반적인 목적의 container_cast 유틸리티 (예 : this answer 참조). 그럼 당신은 쓸 수 :

class A 
{ 
public: 
    A(const std::vector<std::shared_ptr<int>>& list) : internalList(container_cast(list)) {} 
    std::vector<std::shared_ptr<const int>> internalList; 
}; 
+0

위 답변에 대한 추가 사항이 좋습니다. 고마워요. – user18490

+0

'container_cast' 구현은 실제 코드에서 사용하기 전에 사본을 만들고 결코 움직이지 않아야한다는 점에 유의하십시오. ; -] – ildjarn

관련 문제