gpt4 book ai didi

c++ - 如何从 begin() 和 end() 中实现 cbegin() 和 cend()?

转载 作者:行者123 更新时间:2023-11-28 04:36:41 25 4
gpt4 key购买 nike

所以我有一个容器,我为其定义了自己的迭代器。在我的示例中,它是一个 Skiplist,但类型并不重要。

我实现了 begin()end() 我想知道如何实现 cbegin()cend()

有没有办法将迭代器转换为常量迭代器?

这里是我的简化实现:

class Skiplist {
public:
using key_type = int;
using mapped_type = int;
using value_type = std::pair<const key_type, mapped_type>;
using size_type = std::size_t;

template<typename IT> class iterator_base; // template class for iterator and iterator const

using iterator = iterator_base<value_type>;
using const_iterator = iterator_base<value_type const>;

//....

// Iterators
iterator begin() noexcept;
iterator end() noexcept;
const_iterator cbegin() const noexcept; // can this be made by convert iterator to const iterator?
const_iterator cend() const noexcept;

//....
private:
struct Skipnode; // forward declaration so Basenode can have Skiplist*

struct Basenode { // Empty node, mainly created to represent head element.
// Is there a way to get a empty head with no key / values without using this ?
Basenode(int in_level);
Basenode(const std::vector<Skipnode*>& in_next);

std::vector <Skipnode*> next;
};

struct Skipnode : Basenode { // derived so with Basenode* we can start the iteration of the node on head
Skipnode(value_type val, int in_level);
Skipnode(value_type val, const std::vector<Skipnode*>& in_next);

value_type value; // first key / second mapped type = value
};

//....
};


template<typename IT>
class Skiplist::iterator_base {
public:
iterator_base(Skiplist::Skipnode* pos)
: curr{ pos }
{
};

//...

IT& operator*() { return curr->value; }
IT* operator->() { return &curr->value; }

private:


Skiplist::Skipnode* curr;
};



Skiplist::iterator Skiplist::begin() noexcept
{
if (head.next.empty()) return Skiplist::iterator{ nullptr };

return Skiplist::iterator{ head.next[0] };
}

Skiplist::iterator Skiplist::end() noexcept
{
if (head.next.empty()) return Skiplist::iterator{ nullptr };

Basenode* current_position = &head;
while (current_position->next[0] != nullptr)
current_position = current_position->next[0];

return Skiplist::iterator{ current_position->next[0] };
}

Skiplist::const_iterator Skiplist::cbegin() const noexcept
{
if (head.next.empty()) return Skiplist::const_iterator{ nullptr };

return Skiplist::const_iterator{ head.next[0] };
}

Skiplist::const_iterator Skiplist::cend() const noexcept
{
if (head.next.empty()) return Skiplist::const_iterator{ nullptr };

const Basenode* current_position = &head;
while (current_position->next[0] != nullptr)
current_position = current_position->next[0];

return Skiplist::const_iterator{ current_position->next[0] };
}

它与cbegincbegin 非常重复。

那么问题来了,把iterator转换成const_iterator缺少了什么。我尝试了 const_caststatic_cast 但很遗憾它不起作用。

编辑:从评论中我试图创建一个隐式构造函数,但它似乎仍然没有表达出来。这是我尝试过的。

//the constructor in the iterator class:
iterator_base(const iterator_base<IT>& it)
: curr{ it.curr }
{
}

Skiplist::const_iterator Skiplist::cbegin() const noexcept
{
if (head.next.empty())
return Skiplist::const_iterator{ nullptr };

return Skiplist::const_iterator{ begin() }; // this doesnt work
}

最佳答案

一个简单的解决方案是向您的 base_iterator 添加一个 bool is_const 模板参数,并根据此参数调整类型并禁用非常量访问。

示例代码:

template<typename IT, bool is_const> class iterator_base;

using iterator = iterator_base<value_type, /*is_const=*/false>;
using const_iterator = iterator_base<value_type, /*is_const=*/true>;

// ...

template<typename IT, boo is_const>
class Skiplist::iterator_base {
public:
using node_type = typename std::conditional<is_const, Skiplist::Skipnode const, Skiplist::Skipnode>::type;
using value_type = typename std::conditional<is_const, IT const, IT>::type;

iterator_base(node_type* pos) : curr{ pos }{};

value_type & operator*() const { return curr->value; }
value_type * operator->() const { return &curr->value; }

private:
node_type* curr;
};

关于end()cend(),可以简单的定义iterator_base(nullptr)为字符串的结尾。你的代码没用:

while (current_position->next[0] != nullptr)
current_position = current_position->next[0];

// ***** current_position->next[0] == nullptr ******
return Skiplist::iterator{ current_position->next[0] };

关于c++ - 如何从 begin() 和 end() 中实现 cbegin() 和 cend()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51197882/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com