2017-12-16 30 views
0

std::pairstd::vector을 내부적으로 참조 (&)로 작성해야하지만 push_back 참조 값을 시도하면 기능이 중단됩니다. 디버깅 후 참조 주소가 unique_ptr 내부의 주소와 다르다는 것을 알았지 만 값은 동일합니다.벡터 내부에 참조와 쌍을 가질 수 있습니까?

벡터에 삽입하는 함수 (여기서는 foo())를 사용할 때 참조하는 값은 정확하지만 주소는 여전히 일치하지 않습니다.

#include <iostream> 
#include <memory> 
#include <iterator> 
#include <string> 
#include <vector> 

void foo(std::vector<std::pair<const int&, int> >& vector,   
std::unique_ptr<int>& ptr) { 
    vector.push_back(std::make_pair<const int&, int>(*ptr, 11)); 
} 

int main() { 
    std::vector<std::pair<const int&, int> > v; 
    std::unique_ptr<int> i = std::make_unique<int>(1); 
    std::unique_ptr<int> b = std::make_unique<int>(0); 
    foo(v, i); 
    v.push_back(std::make_pair<const int&, int>(*b, 10)); 
    std::cout << v.size() << ": "; 
    for (auto x : v) { 
     std::cout << x.first << ","; 
    } 
    std::cout << "\n"; 
} 

이 코드는 문제를 보여줍니다 - 대신 "2: 1,0,"의 그것은 "2: -342851272,0," (처음부터 또는 유사한 큰 음수)를 출력한다.

어디에 문제가 있습니까?

+3

['std :: reference_wrapper'] (http://en.cppreference.com/w/cpp/utility/functional/reference_wrapper) – StoryTeller

+1

왜 그렇게해야한다고 생각하십니까? –

+0

@NeilButterworth 글쎄, 그들은 (그것의 학교 임무이기 때문에) 함수를 테스트하고이 반환을 기대하고 있습니다. – Davar

답변

3

이후 C++ 14 std::make_pairV1V2 각각 std::decay<T1>::typestd::decay<T2>::type이다

template< class T1, class T2 > 
std::pair<V1,V2> make_pair(T1&& t, T2&& u); 

로 정의된다.

이것은 사용자의 make_pair<const int&, int> 호출이 실제로는 참조가 첫 번째 요소로 쌍을 생성하지 않는다는 것을 의미합니다 (분명히 믿는 것과는 반대). 실제로 pair<int, int> 유형의 임시 사용자를 생성합니다. 이 시점에서 unique_ptr에 저장된 원래 int 개체에 대한 첨부 파일을 잃게됩니다.

pair<int, int> 임시 변수를 push_back으로 전달하면 암시 적으로 벡터의 요소 유형 인 pair<const int&, int> 유형의 임시 변수로 변환됩니다. 이 메커니즘을 통해 벡터 요소 내부의 참조를 make_pair에 의해 생성 된 pair<int, int> 임시 생성자의 구성원 인 int에 첨부합니다 (unique_ptr에 저장되지 않은 객체는). 임시 보관 기간이 만료되면 참조가 사 워집니다. 당신이 모두 make_pair을 피하고 간단하게 직접 올바른 유형, 예를 들어,의 std::pair 객체를 구성하여이 특정 문제를 제거 할 수 있습니다이 경우


vector.push_back(std::pair<const int&, int>(*ptr, 11)); 

그러나 나중에 원시 참조로 인한 다른 문제가 발생할 수 있습니다.

+0

고마워, 나는 직접 건설을 시도하고 지금까지 노력하고있어. (편집 : 예, 실제로 삽입 된 참조 주소는 실제로 unique_ptr.get()과 동일합니다. 왜 정확히 작동하는지 설명해 주시겠습니까? 나중에 원시 참조 문제로 인해, "unique_ptr"메모리 관리를 방해하는 것이 아니라, 아무 것도 가리 키지 않는 것이 "단지"에 관한 것입니까? – Davar