본문 바로가기
C,C++/C++

[C++ STL] 라이브러리 알고리즘의 반복자 인자가 마지막 요소의 다음을 참조하는 이유

by woohyeon 2019. 11. 25.
반응형

라이브러리에서 알고리즘의 범위를 지정하기 위해 2개의 반복자를 지정한다. 
하나는 첫 요소를 참조하기 위한 반복자와, 나머지는 마지막 요소의 다음을 참조하는 반복자이다.
 

컨테이너는 아래와 같은 위치를 참조하는 반복자를 반환하는 멤버 함수를 가지고 있다.

출처: stackoverflow


왜 마지막 요소를 참조하지 않고 마지막 요소의 다음을 참조하는 반복자를 사용할까?

이에는 크게 3가지 이유가 있다.

첫 번째
만약 마지막 요소의 다음이 아닌 마지막 요소를 참조한다면
요소가 없는 컨테이너의 범위, 즉 크기가 0인 범위를 나타낼 경우 요소가 존재하지 않기 때문에
다른 무언가의 방법으로 표현해야 한다.

이는 크기가 0인 컨테이너의 범위와 크기가 1 이상인 컨테이너의 범위를 나타낼 때의 방법이 다르게 되어
혼동을 줄 수 있고 신뢰하기 어렵게 된다.
마지막 요소의 다음을 참조한다면 크기가 0이거나 1이상인 경우에도 동일한 방식으로 표현할 수 있다.


두 번째

두 반복자를 사용해서 반복하여 비교할 경우 다음과 같이 대소 비교할 필요 없이 일치 여부만 확인하면 된다.
!= 연산은 모든 컨테이너의 반복자에서 지원하지만 >, <  연산은 임의 접근 반복자만 지원한다. ( ex. 벡터 )

while(begin != end)
{
    // code
    ++begin;
}

두 반복자가 같지 않을 경우 유효한 범위가 존재한다는 의미이며 begin은 요소를 참조할 수 있는 상태이다.
따라서 위 조건을 만족하는 동안 임의의 코드를 실행 후 begin 반복자를 증가시키며 모든 범위를 탐색할 수 있다.

세 번째
시작을 참조하는 반복자와 마지막 요소의 다음을 참조하는 반복자를 사용하여 범위를 정의하면 범위를 벗어난 상태를
자연스럽게 표현할 수 있다.
표준 라이브러리 알고리즘 대부분은 동작 실패 시 두 번째 반복자인 end를 반환한다.
따라서 fail 값을 따로 정의하지 않아도 간단하게 나타낼 수 있다.

만약 두 번째 요소가 마지막 요소를 참조한다면 fail 값에 대해 따로 정의를 하여 반환해야 할 것이다.
이는 프로그램을 복잡하게 만든다.

또한 우리는 for(int i = 0; i != 10; ++i) 와 같은 표현 방식에 익숙하기 때문에 [a, b) 범위로 표현하는 것이 편하고 간단하다.

이처럼 마지막 요소의 다음을 참조하는 반복자를 사용하는 것이 상대적으로 단순하고 안정적인 프로그램을 작성하는 데 도움이 된다.
때문에 모든 컨테이너 타입은 범위의 끝 이후의 값을 지원해야 한다.




댓글