2011-11-23 7 views
20

컨테이너에서 소유권을 빼앗지 않으면 서 (반복기를 통해) 컨테이너의 unique_ptr 요소에 어떻게 액세스합니까? 컨테이너의 요소에 대한 반복자를 가져 오면 요소 소유권이 여전히 컨테이너와 함께 유지됩니까? unique_ptr에 액세스하기 위해 반복자를 역 참조하는 경우는 어떻습니까? 그것은 unique_ptr의 암시 적 이동을 수행합니까?unique_ptr의 컨테이너를 반복 할 때

컨테이너에 개념적으로 요소가 있고 다른 코드가 컨테이너의 요소를 조작하기를 원한다고해도 컨테이너에 값을 저장하지 않고 요소를 저장해야 할 때 shared_ptr을 많이 사용합니다. 컨테이너에서 소유권을 얻지 않고 실제로 unique_ptr 요소에 액세스 할 수 없다는 것을 두려워합니다.

통찰력이 있으십니까?

답변

13

unique_ptr 사본을 만들지 않으려 고하면 사용할 수 있습니다. shared_ptr처럼 포인터의 값을 얻으려면 이터레이터를 "이중 참조 해제"해야합니다.

Ptr p = v[0]; 

다음은 컴파일 시간에 찾을 수 있습니다 :

#include <vector> 
#include <memory> 
#include <iostream> 

template <class C> 
void 
display(const C& c) 
{ 
    std::cout << '{'; 
    if (!c.empty()) 
     std::cout << *c.front(); 
    for (auto i = std::next(c.begin()); i != c.end(); ++i) 
     std::cout << ", " << **i; 
    std::cout << "}\n"; 
} 

int main() 
{ 
    typedef std::unique_ptr<int> Ptr; 
    std::vector<Ptr> v; 
    for (int i = 1; i <= 5; ++i) 
     v.push_back(Ptr(new int(i))); 
    display(v); 
    for (auto i = v.begin(); i != v.end(); ++i) 
     **i += 2; 
    display(v); 
} 

당신이 할 경우 (실수)를 unique_ptr의 복사본을 만들 : 여기에 간단한 예입니다. 런타임 오류가 발생하지 않습니다. 유스 케이스가 container<unique_ptr<T>>이 만들어진 이유입니다. 상황은 정상적으로 작동해야하며 그렇지 않은 경우 문제는 런타임 대신 컴파일 타임에 나타납니다. 따라서 코드를 제거하고 컴파일 시간 오류를 이해하지 못하면 다른 질문을 다시 여기에 요청하십시오. auto

+0

좋아, 나는 그것이 나를 위해 일을 명확히한다고 생각한다. 나는 새로운 for_each 함수를 사용하는 습관을 지녔지 만 매개 변수가 값으로 전달 된 요소 인 람다를 참조로 사용하지는 않았지만 시도하지 않으려면 unique_ptr 요소에 대한 참조를 만들어야 할 것입니다. 복사/이동. 추신 한 번 반복자를 참조 해제하고 그 결과에 대한 참조를 취하는 경우이 시도가 시도되지 않았다고 가정합니다. 내 말은 : 'for (Container :: iterator it = container.begin(); it! = container.end(); it ++) { unique_ptr & 요소 = &*it; // 시도하지 않은 복사본? }' 감사합니다. Howard, btw. –

+0

예, 정상적으로 작동해야합니다. 비록 코드에 여분의 '&'가 있습니다. 그러나 컴파일러가 어디에서 알려줄 것입니다. –

+0

다음과 같이 역 참조 할 수 있어야합니다 : blah & element = ** it; 여전히 복사본이없는 것 같습니다. (아마도 더 유용 할 것입니다.) –

32

및 범위 기반이 상대적으로 우아하게 위해-루프 C++ 11 :

std::vector< std::unique_ptr<YourClass>> pointers; 
for(auto&& pointer : pointers) { 
    pointer->functionOfYourClass(); 
} 

std::unique_ptr에 대한 참조 &는 복사를 방지하고 역 참조없이 uniqe_ptr를 사용할 수 있습니다.

+0

이 경우'auto &'와'auto && '를 사용하는 것과 다른 점이 있다면 누구에게 알 수 있습니까? 이 참조는 double & http://en.cppreference.com/w/cpp/language/range-for를 보여줍니다. 둘 다 컴파일하는 것 같습니다 – austinmarton

+0

좋은 질문입니다. {auto /&}가 이니셜 라이저에 따라 좌변과 우변으로 작동 할 수 있다고 제안하는 [이 링크] (http://en.cppreference.com/w/cpp/language/auto) (설명/1 참조)를 발견했습니다. 그에 따라 예제를 적용합니다. – Pascal

관련 문제