2010-07-25 12 views
2

Effective C++에서와 사용 CONST, 항목 3C++ : STL 반복자

/* case1 */ const std::vector<int>::iterator i // i acts like a T* const 
/* case2 */ std::vector<int>::const_iterator ci // ci acts like a const T* 

const 적용하는 방법을 기억하기 위해, 나는에 적용되는 기본적 this article

'const를'에서 다음을 기억하는 데 사용 어떤 을 (즉각적인 권리 인 이 무엇이든간에 적용되는 경우에는 제외) 바로 왼쪽에 있습니다.

먼저 책의 항목 3을 읽었을 때 나는 case1과 case2에서 다른 방법으로 사용하기를 기대했습니다.

이 사례는 예외로 취급해야합니까? 아니면 제가 실종되었다는 것을 더 깊이 이해하고 있습니까?

답변

1

인용 된 규칙은 const 키워드에 절대적으로 해당됩니다. 그러나 반복자를 처리 할 때 const_iterator 클래스는 단지 이름이 같으므로 (readonly_iterator 일 수도 있음) const 키워드에 대한 규칙은 적용되지 않습니다.

당신은 그러나이 같은 경우 1을 선언 할 수

std::vector<int>::iterator const i 

당신이 const int x 또는 int const x을 지정할 수 있습니다처럼.

반복기가 가리키는 유형도 컨테이너의 템플릿 매개 변수에 지정되므로 순서는 일반 변수를 선언하는 것과 다릅니다.

여기에 따라야 할 특정 규칙이 있습니다. 게시물의 의견이 맞습니다. const_iteratorconst T*으로 처리하는 방법을 배워야합니다.

5

반복자는 typedef 에디션과 같이 인 것처럼 당신이있는 생각할 수 있습니다 :이 중 하나에 const를 추가 할 때

typedef T* iterator; 
typedef const T* const_iterator; 

, 그것은에, 즉, 최상위 수준에 적용 포인터 자체는 가리키는 객체가 아니라 다음 동등성을 유지합니다.

const iterator it; // is the same as: 
T* const it; 

const const_iterator it; // is the same as: 
const T* const it; 

이들은 예외가 아닙니다. 이것은 모두 typedef 님의 작품입니다.

8

규칙은 광고 한대로 작동합니다.

const std::vector<int>::iterator i 

바로 오른쪽의 항목은 iterator입니다. 반복기는 변경할 수 없습니다. 반복기를 벡터의 다른 항목을 가리 키도록 지정할 수 없으며 늘릴 수 없으며 항상 초기화 된 항목을 가리 킵니다. 그래도 지적하고있는 항목을 변경할 수 있습니다.

이 동작은 거의 동작하지 않으므로 const_iterator typedef가 있습니다.

std::vector<int>::const_iterator ci 

반복기는 이동할 수 있지만 가리키는 항목은 수정할 수 없습니다. 이것은 거의 항상 원하는 것입니다. 벡터를 반복하지만 내용을 수정할 수는 없습니다.

여기에 const 키워드가 없으므로 알아낼 수있는 규칙을 사용할 수 없습니다. 이 경우에는 const_iterator이 문서화되어 있다는 것을 이해해야합니다.

+0

첫 번째 사례가 유용하다는 것을 알게 된 곳 중 하나는'std :: find_if'의 검색 결과를 저장하는 것입니다. 'const std :: vector :: iterator i = std :: find_if (...);'는 검색 결과를 기억하고 싶기 때문에 실수로 결과를 변경하고 싶지는 않습니다. – SCFrench

1

const_iterator가 혼란 스럽다고 생각합니다. 다음은 간단한 typedef 예제입니다.

typedef int* Type; 
typedef const int* ConstType; 

int main() { 
    const Type a; // int * const 
    ConstType b; // const int * 
} 
0

const는 경우 1 반복자 적용되므로 반복자 자체 CONST한다. iterator가 "가리키는"항목에는 아무런 영향을 미치지 않습니다. (이 포인터가 const입니다 T* const,처럼하지 뾰족한-에 T)의 경우 2에서

에서, const이 이름 const_iterator의 한 부분, 그래서 정말이 const 무엇인지 추론 할 수 없다 . 클래스는 나쁜 이름을 가질 수 있으며 그것에 대해 전혀 const가 될 수 없습니다. 그러나이 경우 const_iterator은 표준 라이브러리에서 정의 된 것과 같으므로 대상 요소의 수정을 허용하지 않습니다.