- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
所以我有一个容器,我为其定义了自己的迭代器。在我的示例中,它是一个 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] };
}
它与cbegin
和cbegin
非常重复。
那么问题来了,把iterator转换成const_iterator缺少了什么。我尝试了 const_cast
和 static_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/
我想处理 vector 中的元素一段时间。为了优化这一点,我不想在处理项目时删除它,而是在最后删除所有已处理的项目。 vector::iterator it; for(it = items.begin
我对 perl 中的 const 声明有疑问,并且无法弄清楚差异,请指出有什么不同。 下面是代码: BEGIN { *SIZE = sub() { 2 }; } *ITEM = sub() {
在右值上调用std::vector 和std::begin() 的成员函数.begin() 会导致不同的输出, 如以下测试所示: vector a{ 1, 2, 3 }; vector::iterat
我正在尝试创建自己的 vector 类。目前,我正在为我的 vector 类 Vec 添加一个删除函数。当我将 variable.begin() 传递到 erase 函数参数时,我的代码会报错,但在我
在 c++ 中迭代 vector 时,我注意到标准库中有一个 begin() 函数,还有一个 begin() 作为成员函数vector 类。如果有的话,两者之间有什么区别,应该使用哪个而不是另一个?
为什么标准将 end() 定义为末尾,而不是实际末尾? 最佳答案 最好的论据是Dijkstra himself 提出的论据。 : 您希望范围的大小是一个简单的差异end - begin; 当序列退化为
我正在尝试遍历大量记录并处理它们中的每一个。即使在处理过程中发生错误,游标也应该继续循环遍历记录,但在批处理结束时,我希望看到所有产生错误的记录的错误消息。 我有以下代码: 选择.... OP
这个问题在这里已经有了答案: error: no matching function for call to 'begin(int*&)' c++ (3 个答案) 关闭 6 年前。 我想获取数组的长
如果我有 std::vector(它是一个 std::vector 并且永远是一个 std::vector)。 使用 std::begin() 代替 std::vector::begin()(或相反)
这个问题在这里已经有了答案: Why use non-member begin and end functions in C++11? (7 个答案) 关闭 4 年前。 在这个问题(https://
我一直在尝试在网络上查找有关这些陈述之间差异的信息,在我看来它们是相同的,但我找不到对此的确认或两者之间的任何类型的比较。 这样做有什么区别: BEGIN -- Some update, in
我正在使用 Tiled Map 学习 LibGDX。我遇到了以下两种渲染方法。第一个是我通常使用的简单的。 但是,我不明白为什么我们需要第二个。我可以使用 batch.begin();在方法 2 中也
是否可以在 SpriteBatch begin 和 end 调用之间使用 ShapeRenderer 绘制形状。 我已经尝试过但没有结果,只绘制了 SpriteBatch 纹理,场景中没有任何形状。示
嗨,我正在编写一个程序,该程序从 .pem 文件导入私钥并创建一个私钥对象以供稍后使用。我遇到的问题是一些 pem 文件头以 开头 -----BEGIN PRIVATE KEY----- 而其他人则以
关闭。这个问题是off-topic .它目前不接受答案。 想改善这个问题吗? Update the question所以它是 on-topic对于堆栈溢出。 9年前关闭。 Improve this q
观看 Stephan T. Lavavej:核心 C++ #1,并注意到他使用的是 begin(collection) 而不是 collection.begin()。 有什么优势? 最佳答案 我想到的
Python脚本 ''' a ''' from __future__ import print_function 运行良好(即什么都不做),但是 ''' a ''' ''' b ''' from __
如何在两种风格的公钥格式之间进行转换, 一种格式是: -----BEGIN PUBLIC KEY----- ... -----END PUBLIC KEY----- 另一种格式是: -----BEGI
我是 STL c++ 的新手。我从书中复制了这个函数: string ConverToLowerCase(string s) { transform(s.begin(), s.end(),
给定代码: #include #include #include #include using namespace std; int main() { string s("ABCDE
我是一名优秀的程序员,十分优秀!