2017-12-18 8 views
9

왜이 코드는 내가 예상 한대로 작동하지 않습니까?범위 루프 용 벡터가 포함 된 참조 해제 된 unique_ptr을 반복합니다.

for (auto it: *std::make_unique<std::vector<int>>(std::vector<int>({1, 2, 3, 4, 5}))) 
    std::cout << it << std::endl; 

벡터 객체가 루프의 첫 번째 반복을 실행하기 전에 파괴

+1

C++ 20에서는 여기에 설명 된 "범위 기반의 초기화 구문"문을 통해 이런 종류의 함정을 피할 수 있습니다. https://herbsutter.com/2017/11/11/ trip-report-fall-iso-c-standards-meeting- 앨버 커키 /. 즉, 'unique_ptr'을 별도로 선언하여 전체 루프에 대해 유효하게 만든 다음 역 참조를 반복 범위로 사용합니다. –

+1

간단히'for (auto it : {1, 2, 3, 4, 5})'를 쓰지 않는 이유는 무엇입니까? 더 복잡한 경우에는'std :: vector '대신에'std :: unique_ptr >'을 사용해야하는 이유가 있습니다. – Jarod42

+0

예, 문제 영역을 보여주는 매우 고안된 예이지만 과장된 방식입니다. :) –

답변

11

range-based for loop 추가하는 것과 같습니다 range_expression를 들어

{ 
    init-statement 
    auto && __range = range_expression ; 
    ... 
} 

, 그것은 것

auto && __range = *std::make_unique<std::vector<int>>(std::vector<int>({1, 2, 3, 4, 5})); 

하지만

0 임시을 반환 range_expression가 수명이 r- 수치 참조 __range 결합으로 나타낸 바와 같이, 루프의 단부까지 연장하지만, range_expression 내의 임시의 수명이 연장되지 않도록 조심 경우

.

무엇 std::make_unique 수익률은 파괴됩니다 전체 표현 후, 임시 std::unique_ptr이다. 즉, 그곳에서 관리되는 std::vector도 파괴 될 것입니다. 임시 std::unique_ptr에서 가져온 std::vector이 전달 참조에 바인딩되어 있지만 수명이 연장되지 않습니다.

C++ 20에서 init-statement를 사용하면 해결할 수 있습니다.

for (auto p = std::make_unique<std::vector<int>>(std::vector<int>({1, 2, 3, 4, 5})); auto it : *p) 
    std::cout << it << std::endl; 
+1

그 페이지에서 : "range_expression이 임시를 반환하면, 그 값은 rvalue 참조'__range'에 대한 바인딩으로 표시된 것처럼 루프의 끝까지 확장되지만'range_expression '연장되지 않았다. " – 0x5453

+0

끈적 끈적한 구문 설탕이에요, 고마워요. – Daniil

관련 문제