如何编写一个迭代器包装器来组合底层迭代器中的顺序值组
How can I write an iterator wrapper that combines groups of sequential values from the underlying iterator?
考虑以下顺序:
1, 2, 3, 4, 5, 6, 7, 8, 9, 10
对于该序列,我有输入迭代器。我想把这些迭代器包装在迭代器上,生成以下序列:
(1,2), (3,4), (5,6), (7,8), (9,10)
如果不清楚的话,这个序列是由原始元素的连续元素对组成的序列。虽然原始序列有10个元素,但这一个有5个:每个元素都是从原始序列中的两个元素中获得的。
我正在使用Boost的iterator_facade
来实现这一点,我在这方面有一个错误的尝试:
template <typename Iterator>
struct pairing_iterator
: boost::iterator_facade<
pairing_iterator<Iterator>,
std::array<typename std::iterator_traits<Iterator>::value_type, 2>,
std::input_iterator_category
// I should probably customize reference too, but it's not relevant
> {
pairing_iterator(Iterator it) : it(it) {
increment(); // A
}
pairing_iterator::value_type dereference() const {
return pair;
}
bool equal(pairing_iterator const& that) const {
return it == that.it; // B
}
void increment() {
pair = { { *it++, *it++ } };
}
Iterator it;
pairing_iterator::value_type pair;
};
我面临的一个问题是在标有A的行上:当传入的迭代器是一个结束迭代器时,这将导致它递增,而我不能这样做
另一个是在用B标记的行上:我保持底层迭代器总是在"当前"对之前,所以如果迭代器在最后一对,那么底层迭代者将是一个结束迭代器,因此将true与结束pairing_迭代器进行比较。
如果底层迭代器是正向迭代器,我可以在每次解引用时读取对,并在增量时前进两次。但是使用输入迭代器,我只能读取一次。
我是不是在重新发明一个已经存在的轮子?我在Boost中没有发现这样的东西,这让我有点惊讶。但我很想找到一个现成的解决方案。
如果这个轮子还没有出来,我怎么能让它真正滚动呢?
我有两个建议,你已经在聊天中否决了,一个有更温和但相对安全的限制,另一个有一个丑陋的限制解决方法:
第一个想法非常简单,但在每次推进之前只需要一个解引用
template <typename Iterator>
struct pairing_iterator
: boost::iterator_facade<
pairing_iterator<Iterator>,
std::array<typename std::iterator_traits<Iterator>::value_type, 2>,
std::input_iterator_category
// I should probably customize reference too, but it's not relevant
> {
pairing_iterator(Iterator it) : it(it) {
}
pairing_iterator::value_type dereference() const {
auto t = *it++;
return { { std::move(t), *it } };
}
bool equal(pairing_iterator const& that) const {
return it == that.it;
}
void increment() {
++it;
}
Iterator it;
};
第二个想法消除了一个取消引用的限制,但又丑陋又奇怪:
template <typename Iterator>
struct pairing_iterator
: boost::iterator_facade<
pairing_iterator<Iterator>,
std::array<typename std::iterator_traits<Iterator>::value_type, 2>,
std::input_iterator_category
// I should probably customize reference too, but it's not relevant
> {
pairing_iterator(Iterator it) : it(it), dereferenced(false) {
}
pairing_iterator::value_type dereference() const {
if (!dereferenced) {
auto t = *it++;
pair = { { std::move(t), *it } };
dereferenced = true;
}
return pair;
}
bool equal(pairing_iterator const& that) const {
return it == that.it;
}
void increment() {
if (!dereferenced)
dereference();
dereferenced = false;
++it;
}
Iterator it;
pairing_iterator::value_type pair;
bool dereferenced;
};
我可能犯了几个错误,但希望这足以描述这些概念。
template<typename T>
struct piterator {
typedef std::pair<typename std::iterator_traits<T>::value_type,
typename std::iterator_traits<T>::value_type> value_type;
piterator(){}
piterator( const T& t, const T& e):itr(t),eitr(e){
if( itr != eitr ) head.first = *itr;
if( itr != eitr )head.second = *(++itr);
}
bool operator ==( const piterator& e )const {
return e.itr == itr && e.eitr== eitr;
}
value_type& operator*(){ return head; }
const value_type& operator*()const { return head; }
value_type& operator->(){ return head; }
const value_type& operator->()const { return head; }
piterator& operator++() {
if( itr != eitr )head.first = *(++itr);
if( itr != eitr )head.second = *(++itr);
return *this;
}
piterator& operator++(int) {
if( itr != eitr )head.first = *(++itr);
if( itr != eitr )head.second = *(++itr);
return *this;
}
private:
T itr;
T eitr;
value_type head;
};
需要进行额外的检查,以确保配对迭代器不会"超过"奇数大小列表的末尾。
相关文章:
- 使用std::multimap迭代器创建std::list
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- C++中带有List类的迭代器Segfault
- 如何在c++迭代器类型中包装std::chrono
- 集合上的输出迭代器:assign和increment迭代器
- Boost Spirit,获取迭代器内部语义动作
- 对于set上的循环-获取next元素迭代器
- 为什么output_editor Concept不需要output_e迭代器标记
- c++17文件系统::recursive_directory迭代器()在mac上没有给出这样的目录,但在windows上
- 使用迭代器时如何访问对象在向量中的位置?
- std::vector::迭代器是否可以合法地作为指针
- 跟随整数索引列表的自定义类迭代器
- 不明白迭代器,引用和指针失效,一个例子
- 我可以使用反向迭代器作为ForwardIt吗
- ESP8266单片机矢量迭代器的C++问题
- 将多个 for 循环组合成单个迭代器
- 实现迭代器,以许多向量的组合
- 如何编写一个迭代器包装器来组合底层迭代器中的顺序值组
- 根据运行时决策组合不同的迭代器
- 如何在C++11中编写一个简单的、类型擦除的可组合迭代器