2012-10-02 57 views
0

这是一些背景。我有一个二叉树迭代器(按顺序说)。它通过将指针放在堆栈顶部来跟踪当前节点的父节点。现在我还想要互操作性,即能够将iterator投射到const_iterator。但iteratorstd::stack<pointer>const_iteratorstd::stack<const pointer>有没有办法将std :: stack <pointer>转换为std :: stack <const 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上使用[范围形式的插入](http://en.cppreference.com/w/cpp/container/deque/insert)在一些CRT实现中它可以快得多。至于使用'deque'而不是'stack' - 默认情况下,它们是相同的底层数据结构。 'std :: stack '只是一个为其他容器提供堆栈语义的适配器;默认情况下通常是deque。 (我认为它也可能是矢量,但我不记得确切) –

+0

@BillyONeal这是'deque' AFAIK。 – Hindol

回答

1

只需在const_iterator中保留一个非const堆栈即可。这是一个私人数据成员,所以它并不重要。

确保您的const_iterator实现不会通过指针进行修改。要确保双重确认,请始终使用const_iterator自己的运算符*(),该运算符应该返回一个const引用。 (实际上,我认为你不需要对指针进行多余的引用,但是如果你这么做的话,你应该这样做。)

+0

我知道这是一个可能的解决方案,但在_const iterator_中有一个_non-const pointer_错误我。 – Hindol

+0

@Hindol:这没有任何意义。迭代器的常量指的是它所包含的内容的常量:指针。但是指针本身可以是const或非const的;它与你是否有一个const_iterator指向它完全无关。 –

+0

@BillyONeal我很抱歉,我的意思是_pointer-to-const_。 – Hindol

0

在C++中没有简单的方法来完成这些类型的转换。它看起来像一个演员就足够了,但它不这样工作。

C++的方式是隐藏关键的数据结构和管理不同API的访问。 是的,这意味着你有一个比你想要的更少const。但这就是隐藏的目的。 只要在实现中,没有其他人可以滥用它。

如果你在一个专门的类中封装你的堆栈/ deque /无论[我猜vector会是充足的],你可以非常接近想要的解决方案。它在内部保留非const指针,但所有const方法返回const pointer s。如果您的迭代器只能通过getter访问它,则无法绕过const意外。

+0

由于我使用'boost :: iterator_facade',所以安装有点复杂。只要我使用'Iterator ',constness就会传播给其他许多类型('node_pointer'就是其中之一)。尽量避免使用“const指针”比使用“std :: deque”要多得多。 – Hindol

+1

到目前为止,我还没有使用过'iterator_facade'。看看这些文档,我不确定是否值得付出努力。特别是如果迭代器不仅仅包含一个指针。复制似乎是不可避免的。我用迭代器写了一些东西,可能与你的相似(向量为缓存)。 Iterator来自ConstIterator,所以互操作性是免费的。当然'ConstIterator'在数据结构中包含非常量指针,但由于所有有问题的方法本身都是常量,所以几乎不存在混合的风险。 – rtlgrmpf

相关问题