2012-12-18 5 views
3

이해하려고하는 (주석 처리되지 않은 ...) 소스 파일이 있습니다. (de) 참조 연산자 평가

static const Map *gCurMap; 
static std::vector<Map> mapVec; 

auto e = mapVec.end(); 
auto i = mapVec.begin(); 
while(i!=e) { 
    // ... 
    const Map *map = gCurMap = &(*(i++)); 
    // ... 
} 

나는 &(*(i++))가 무엇을 이해하지 않습니다. 그것은 단지 i++을 사용할 때 컴파일되지 않지만 "증분"이기 때문에 같은 모양이됩니다. i, 주어진 주소에서 값을 요청한 다음이 값의 주소를 요청하고 있습니까?!

답변

4

전혀 아닙니다. &*xoperator&(operator*(x))과 같으며 원하는 것이면 모두 가능합니다.

&*pp과 동일 함을 포인터 타입 T * p 같은 만 사실이다. 하지만 C++에는 사용자 정의 형식과 오버로드 가능한 연산자가 있습니다.

역 참조 연산자 (*)는 일반적으로 iterator가 컨테이너 요소에 대한 참조를 반환하도록 오버로드됩니다. 앰퍼샌드 연산자 (&)가 컨테이너 요소에 미치는 영향은 클래스 작성자가 결정합니다. 무조건 주소를 사용하려면 std::addressof(*i++) (­ vou ­ 정자 헤더 <memory>)을 사용해야합니다.

3

mapVec.begin()은 오버로드 된 operator++의 반복기를 반환합니다. iterator의 "dereference"(오버로드 된 operator*)는 map 개체를 가져 오는 것입니다. 참조 &map이 포인터이기 때문에 i의 역 참조에서 개체의 주소에 할당됩니다. i++은 여전히 ​​반복자이므로 실제 map 개체가 아니기 때문에 간단히 처리 할 수 ​​없습니다.

2

i은 반복자이며, *i은 해당 반복자가 가리키는 개체이며 &*i은 해당 개체의 주소입니다. iterator가 평범한 오래된 포인터라면, 이것은 불필요 할 것이다. 그러나 보통 그렇게 간단하지는 않다. 반복기는 대개 포인터를 가리키는 객체에 액세스 할 수 있도록 operator*을 오버로드하는 일부 클래스 유형입니다. 이것은 기본적으로 반복자에서 요소로의 변환이며 그 요소에 대한 포인터로의 변환입니다.

나는 주어진 라인을 이해하기가 더 어렵 기 때문에 증가분을 다음 라인으로 옮길 것이다. i++의 값이 단지 i이고 이후 증가분이 발생하기 때문에 이것은 동일합니다.

2

동일하지 않습니다. i은 반복기입니다. 이터레이터를 참조 해제하면 일부 객체에 대한 참조 즉, T의 경우 T&이 생성됩니다. 그러한 객체의 주소를 취하는 것은 T*, 즉 위치 i에있는 객체의 주소를 산출한다. 반복자가 같은 표현식에서 또한 증가한다는 것은 세부 사항 일 뿐이며 나쁜 생각 일 수 있습니다 (후행 증가는 일반적으로 사전 증가보다 효율적이지 않으며 코드 발췌 부분에 반복자를 증가시킬 필요가 없습니다). 다른 위치에서 사전 증분).