不幸的是,我没有收到答案,所以这就是我所做的。也许一个丑陋的解决方案会激起某人发布更好的东西:-)
背景
所以我学到的第一件事就是std::reverse_iterator
封装一个“正常”迭代器(称为current
,可通过 访问base()
)并建立反向迭代器的关系,即比“正常”迭代器“向左多一个元素”。
(图片来自cppreference.com)
通用解决方案
只要“普通”迭代器具有标准接口并且不使用任何附加功能,这些行
using reverse_iterator = std::reverse_iterator<iterator>;
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
足以自动将您自己的迭代器类转换为反向迭代器。
并带有成员函数
reverse_iterator rbegin() { return reverse_iterator(end()); }
reverse_iterator rend() { return reverse_iterator(begin()); }
const_reverse_iterator crbegin() const { return const_reverse_iterator(cend()); }
const_reverse_iterator crend() const { return const_reverse_iterator(cbegin()); }
反向迭代是可能的,例如像这样的代码
for (my_container::reverse_iterator rit = c.rbegin(); rit != c.rend(); ++it)
{
// rit will iterator container c in reverse order
}
作品。
向迭代器添加更多功能
正如我在问题中所写,我iterator
用两个额外的成员扩展了这个类,key()
并且value()
. 前者允许在迭代期间快速访问 JSON 对象的键。后者是 writeit.value()
而不是*it
. 不幸的是,上述方法没有将这些函数继承到reverse_iterator
.
为了丰富用户定义的反向迭代器,我们需要继承std::reverse_iterator<iterator>
基迭代器并将调用委托给基迭代器。不幸的是,我发现除了手动执行此操作之外没有其他方法。对于上述功能,如下所示:
class reverse_iterator : public std::reverse_iterator<iterator>
{
...
std::string key() const
{
auto it = --this->base();
return it.key();
}
reference value() const
{
auto it = --this->base();
return it.operator * ();
}
}
最棘手的部分是您需要手动实现“一对一”关系:
- 通过 检索基本迭代器
base()
。
- 将其递减以指向“右”(实际上是左...)元素。
- 调用所需的函数。
有了这个,我们几乎完成了。几乎,因为...
在上面的代码中。剩下要做的就是将所有其他调用委托operator++
给基类等函数。我现在找到了让其他人参加这个无聊代表团的方法。
所以该类包含如下代码
using base_iterator = std::reverse_iterator<iterator>;
reverse_iterator operator++(int)
{
return base_iterator::operator++(1);
}
reverse_iterator& operator++()
{
base_iterator::operator++();
return *this;
}
(注意 的定义base_iterator
。)
而已。我们现在有用户定义的反向迭代器,它允许我们编码
for (my_container::reverse_iterator rit = c.rbegin(); rit != c.rend(); ++it)
{
std::cout << rit.key() << '\n';
}
打扫干净
在 Github 上的讨论中,gregmarr提议将reverse_iterator
和const_reverse_iterator
类组合成一个模板类,例如
template<typename Base>
class json_reverse_iterator : public std::reverse_iterator<Base>
{
public:
/// shortcut to the reverse iterator adaptor
using base_iterator = std::reverse_iterator<Base>;
/// the reference type for the pointed-to element
using reference = typename Base::reference;
/// create reverse iterator from iterator
json_reverse_iterator(const typename base_iterator::iterator_type& it)
: base_iterator(it) {}
/// create reverse iterator from base class
json_reverse_iterator(const base_iterator& it) : base_iterator(it) {}
...
}
这允许写
using reverse_iterator = json_reverse_iterator<iterator>;
using const_reverse_iterator = json_reverse_iterator<const_iterator>;
并且要快乐。
完整示例
有关完整代码,请参见此处。
我仍然希望看到一种避免重复大多数功能的解决方案,但这对我来说已经足够了。由于我已经有一段时间没有找到更好的东西了,所以我决定分享它。