2012-10-02 2 views
0

다음은 배경입니다. 나는 이진 트리 이터레이터 (in-order)를 가지고있다. 그것은 스택의 맨 위에 포인터를 밀어 현재 노드의 부모 노드를 추적합니다. 이제 나는 상호 운용성을 원합니다. 즉, iteratorconst_iterator으로 변환 할 수 있습니다. 그러나 iteratorstd::stack<pointer>이고 const_iteratorstd::stack<const pointer>입니다.std :: stack <const pointer>에 std :: stack <pointer>을 변환하는 방법이 있습니까?

동일한 효과를 얻는 다른 방법도 있습니다.

편집

은 현재 내가 완전히 std::stack를 사용하는 아이디어를 폐기했다. std::dequepush_back() + pop_back() + back()입니다. std::deque<pointer>std::deque<const pointer>으로 변환하려면 std::copy(std::begin(ptrDeque), std::end(ptrDeque), std::begin(constPtrDeque));을 사용하고 있으며이 설정은 이며 간단히 작동합니다.입니다.

나는 여전히 호기심에서이 질문에 대한 답변을 원합니다.

+0

변형이 좀 더 복잡하면'std :: transform'을 사용할 수도 있습니다. 이 경우'std :: copy'가 좋습니다. – Naveen

+0

'std :: copy' 대신에 deque에 [range form of insert] (http://en.cppreference.com/w/cpp/container/deque/insert)를 사용해야합니다. 일부 CRT 구현에서는 훨씬 더 빠를 수 있습니다. 'stack' 대신에'deque'를 사용하는 것에 관해서는 기본적으로 그것들은 같은 기본 데이터 구조입니다. 'std :: stack '은 다른 컨테이너에 스택 의미를 제공하는 어댑터 일뿐입니다. 이는 기본적으로 deque입니다. (나는 또한 벡터일지도 모른다고 생각하지만 정확히 기억하지는 않는다) –

+0

@BillyONeal 그것은 'deque' AFAIK이다. – Hindol

답변

1

const_iterator에 비 const 스택 만 보관하십시오. 그것은 개인 데이터 멤버이므로,별로 중요하지 않습니다.

const_iterator 구현이 포인터를 통해 수정하지 않는지 확인하십시오. 확실하게하기 위해서 const 참조자를 리턴해야하는 const_iterator 자신의 연산자 *()를 항상 사용하십시오. (실제로 포인터를 많이 참조 해제 할 필요는 없다고 생각 합니다만, 그렇게하면, 그렇게해야합니다.)

+0

이것이 가능한 해결책이지만 _const iterator_ _non-const 포인터 _를 사용하면 버그가 있습니다. – Hindol

+0

@Hindol : 그건 의미가 없습니다. iterator의 constity는 포인터가 포함하고있는 constity를 가리킨다. 포인터. 그러나 포인터 자체는 const 또는 non const 일 수 있습니다. const_iterator를 가리키는 지 여부와 완전히 관련이 없습니다. –

+0

@BillyONeal 죄송합니다. 나는 _pointer-to-const_를 의미했습니다. – Hindol

0

C++에서 이러한 종류의 변환을 수행하는 쉬운 방법은 없습니다. 캐스트가 충분할 것으로 보이지만 이렇게하면 작동하지 않습니다.

C++ 방식은 중요한 데이터 구조를 숨기고 다른 API로 액세스를 관리하는 것입니다. 그렇습니다. 즉, 한 점에서 원하는 것보다 덜 const입니다. 그러나 그것이 숨어있는 것입니다. 구현에만있는 한 아무도 다른 사람이 악용 할 수 있습니다.

전용 클래스에서 스택/큐/무엇이든간에 [vector이 만족할 것 같아요] 캡슐화하면 원하는 솔루션에 매우 근접 할 수 있습니다. 내부적으로 비 const 포인터를 유지하지만 모든 const 메서드는 const pointer을 반환합니다. 반복자가 getter를 통해서만 접근한다면, 우연히 const을 우회 할 수 없어야합니다.

+0

설치 프로그램은'boost :: iterator_facade'를 사용하기 때문에 조금 더 복잡합니다. 'Iterator '를 사용하자마자, constness는 다른 많은 타입들로 전파됩니다 ('node_pointer'도 그 중 하나입니다). const 포인터를 피하려고 시도하는 것은'std :: deque'를 사용하는 것보다 훨씬 더 많은 작업입니다. – Hindol

+1

지금까지'iterator_facade'를 사용하지 않았습니다. 문서를 보면 그만한 가치가 있는지 확신 할 수 없습니다. 특히 이터레이터에 포인터 이상이 포함되어 있지 않은 경우. 복사는 피할 수없는 것처럼 보입니다. 나는 반복자 (iterator)를 써서 당신과 비슷한 (캐시와 같은 벡터) 몇 가지 물건을 썼다. 거기에'반복자'는'ConstIterator'에서 파생되므로 상호 운용성은 무료입니다. 물론'ConstIterator'는 데이터 구조에 비 const 포인터를 포함하고 있습니다. 그러나 문제의 모든 메소드는 const 자체이기 때문에 혼동의 위험이 거의 없습니다. – rtlgrmpf

관련 문제