2011-11-29 9 views
4

그래서지도 const_iterator를 에뮬레이트하는 스마트 반복기가 있으며 내부적으로 반환 유형을 만들어야합니다. 분명히, 나는 그것을 수정해야하기 때문에 pair<Key, Value>을 저장하고 싶다. (동시에 수정할 필요가있다.) 동시에 dereference 함수를 pair<const Key, Value> (실제로는 const pair<const Key, Value>&const pair<const Key, Value>*이 될 것이다.)으로 표현하고 싶다. . 지금까지 내놓은 유일한 해결책은 반복자 클래스가 가리키는 값을 변경할 때마다 새로운 쌍을 동적으로 할당하는 것입니다. 말할 필요도없이 이것은 좋은 해결책이 아닙니다.<Key, Value> 쌍을 <const Key, Value> 쌍으로 캐스팅 할 수 있습니까?

또한 *const_cast<const pair<const Key, Value> >(&value)을 시도했습니다. valuepair<Key, Value>으로 표시됩니다.

도움이된다면 크게 도움이 될 것입니다.

호기심에 대한

편집 : 내 반복자 클래스의 pair<const Key, Value> p를 저장 끝났다. 이 변경 될 수 있도록 한 쌍을 변경하기 위해 나는 다음과 같이 별도로 키를 보내고 기본 반복자 (map<Key, Value>::const_iterator it), const_cast에 따라 두 가지 요소를 변경 :

*const_cast<Key*>(&p.first) = it->first; 
p.second = it->second; 

아니 솔루션 난 정말 행복 해요 와 함께하지만, 그것은 일을 끝내고, 참조 할 수있는 올바른 유형의 것을 저장하고 있기 때문에 참조 해제 방법이 행복합니다.

+3

문제가 있습니까? –

+5

** 노력하지 않고도 작은 글을 게시하는 데 많은 시간을 할애해야한다고 생각하기는 어렵습니다. ** std :: pair p (1,2); std :: pair q = p; // fine' –

+2

@Kerrek SB : 당신이 Op의 질문에서 중요한 부분을 간과했다고 생각합니다. 그는 자신의 커스텀 반복자의 역 참조/멤버 선택 연산자가 호출 될 때마다 새로운 쌍 객체를 생성하는 것을 피하고자합니다. 이것은 반복자가 잠재적으로 멤버 쌍을 저장하고 함수가 호출 될 때마다 또는 iterator가 증가/감소 될 때마다 복사해야한다는 것을 의미하므로 연산자에서 특히 중요합니다. – stinky472

답변

6

당신은 pair<const Key,Value>에 유형 pair<Key,Value>을 변환 할 수 있습니다. 주어진 pair<Key,Value>가 같은 객체를 참조 pair<const Key,Value>포인터 또는 참조을 만들 수 있다면

그러나, 질문을주의 깊게 읽고, 당신은 실제로 요구하고 있습니다.

대답은 아니오입니다. 한 유형에 대한 참조 또는 포인터가 다른 유형의 객체를 참조 할 수있는 유일한 상황은 객체 유형이 참조 된 유형을 상속하는 경우뿐입니다.

한 가지 가능성은 참조하려는 쌍에서 만든 참조 (pair<const Key&, Value&>) 쌍을 반환하는 것입니다.

+0

감사합니다. 참조 쌍 솔루션이 내 특정 문제를 해결할 수 있는지 알아 봅니다. (주의 깊게 읽어 주셔서 감사 드리며 앞으로 더 명확하게 표현하겠습니다.) – masaers

5

예.

std::pair<int, double> p(1,2); 
std::pair<const int, double> q = p; // no problem 

//q.first = 8; // error 
q.second = 9; 

int b; double d; 
std::pair<int &, double &> s(b,d); 
std::pair<int const &, double &> t = s; // also fine 
+0

필자의 경우, 이것은 컴파일에 실패한 임시 참조를 반환하는 경우로 이어질 수 있습니다. – masaers

+1

@ MarkusSaers :'pair p'를 감안할 때 임시 변수를 만들지 않는'pair (p.first, p.second)'를 반환 할 수 있습니다. –

2

Kerrek SB가 지적한대로 std::pair<const Key, Value>std::pair<Key, Value>에서 구성 할 수 있습니다. 그러나 원래의 질문은 iterator가 참조 해제 될 때마다 std :: pair 객체를 생성하지 않으려한다는 것을 의미합니다.

불행히도, 이것을 수행하는 좋은 방법은 없습니다. 당신은 pair 객체를 생성해야하고 실제로 operator->와 같은 어딘가에 저장할 필요가 있습니다. 그렇지 않으면 당신의 맵을 실제로 pair<const Key, Value>을 저장하여 이터레이터에서 참조/포인터를 리턴 할 수 있어야합니다. 기본적으로 참조/포인터를 반환하려면 해당 형식의 어딘가에 저장해야합니다. 일시적 일 수는 없습니다.

const_cast를 피하십시오. 이것은 꽤 자주 작동 할지라도이 방법으로 쌍을 캐스팅 할 때 정의되지 않은 동작을 요구하는 것입니다.

0

정확히 같은 문제가 발생했습니다. 내 해결책은 iterator 클래스의 일부로 새 맵 객체를 만든 다음 업스트림 맵 클래스에서 누락 된 멤버를 추가하고 그 멤버에 대한 참조를 반환하는 것이 었습니다. 별로 효율적이지는 않지만 작동합니다. 에 const_cast가 정의되지 않은 동작입니다으로 CONST 변수를 지정

  1. :

    귀하의 솔루션은 두 가지 문제가 있습니다. 컴파일러 최적화는 이상한 결과를 제공 할 수 있습니다.

  2. 새로운 참조가 없으면 이전 참조 취소의 결과가 무효화됩니다. 그렇게해서는 안됩니다. 따라서 반복기의 사용법에 따라 이상한 결과가 발생할 수도 있습니다.
+0

하지만 제 경우에는 업스트림 맵 객체가 없습니다 (참조 할 수있는 std :: pair 요소를 포함하지 않는 사용자 정의 컨테이너 클래스입니다.) – masaers

+0

여전히 내부 임시 표준을 만들 수 있습니다 :: iterator 인스턴스가 파기 될 때 : 모든 iterator의 pair 요소는 역 참조를 역 참조하고 파괴합니다. – Denis