2014-10-07 2 views
4

다음 프로그램이 정의되지 않은 동작을 호출합니까?값 초기화 된 반복자와 비교하는 것이 잘 정의되어 있습니까?

#include <iostream> 
#include <iterator> 

int main(int argc, char* argv[]) 
{ 
    for (auto it = std::istream_iterator<std::string>(std::cin); 
     it != std::istream_iterator<std::string>(); 
     ++it) 
    { 
     std::cout << *it << " "; 
    } 

    return 0; 
} 

4 year old question은 비교 될 수 없다는 :

반복자는 모든 컨테이너와 연관되지 않은 특이 값을 가질 수 있습니다. [예 : 초기화되지 않은 포인터 x (int * x;와 같이)를 선언 한 후 x는 항상 포인터의 단일 값을 가져야한다고 가정해야합니다. ] 대부분의 표현식 결과는 특이 값에 대해 정의되지 않은 입니다. 유일한 예외는 특이 값을 갖는 반복자에 대해 비 특이 값의 할당 입니다.

는 그러나 또 다른 대답은 C++ 14 표준에 대해 말한다 :

는하지만, 값 초기화 반복자는 비교 될 수 있으며, 동일한 유형의 다른 값으로 초기화 반복자와 동일한 비교된다.

+0

루프를 끝낼 때 (또는 예상 한대로) 반복자를 이런 식으로 사용하지 않았습니까? –

+1

그 루프는 실제로 잘 정의되어 있습니다. 다른 반복자 루프와 같습니다. 끝날 때까지 루핑을 시작해야합니다. 예를 들어, 호출에 입력 스트림 반복기를 사용하는 것은 매우 일반적입니다. ['std :: copy'] (http://en.cppreference.com/w/cpp/algorithm/copy) 스트림의 모든 값을 벡터로 가져 오려면 예를 들어 [this' std :: istream_iterator' 참조 페이지] (http://en.cppreference.com/w/cpp/iterator/istream_iterator). –

+1

당신은 iterator를 비교하고 dereferencing end()가 정의되지 않은 역 참조 된 iterator의 값을 비교할 것을 두려워합니다. –

답변

10

서로 다른 두 가지 문제가 있습니다.

istream_iterator은 입력 반복자가 아니므로 앞으로 반복기가 아니므로 인용 한 C++ 14 변경 내용이 전혀 적용되지 않습니다. 이러한 비교가 가능하도록 명시 적으로 지정되었으므로 istream_iterator을 이러한 방식으로 비교할 수 있습니다. 기준은 (§24.6.1 [istream.iterator])

인수없이 생성자 istream_iterator() 항상 사용할 수있는 유일한 합법적 반복자 인 스트림의 마지막 입력 반복자 객체를 구축 말한다 종료 조건. [...]

두 개의 스트림 끝 반복자는 항상 같습니다. end-of-stream 반복자는 end-of-stream 반복자와 같지 않습니다. 스트림이 아닌 두 개의 이터레이터는 동일 스트림 인 에서 구성 될 때 동일합니다.

일반적으로 양방향 및 무작위 액세스 포워드 이터레이터의 경우 값 초기화 반복기는 C++14에서 서로 비교됩니다. 표준 라이브러리가이를 구현한다면, 값으로 초기화 된 두 개의 이터레이터를 비교할 수 있습니다. 이를 통해 기본 컨테이너없이 빈 범위를 만들 수 있습니다. 그러나 비표준 반복자를 값 초기화 반복자와 비교할 수는 없습니다. 다음 코드는 C++ 14에서도 정의되지 않은 동작을합니다.

std::list<int> l; 

if(l.begin() == std::list<int>::iterator()) 
    foo(); 
else 
    bar(); 
관련 문제