考虑以下顺序:
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 的行上:我保持底层迭代器始终在“当前”对之前,所以如果迭代器在最后一对,则底层迭代器将是结束迭代器,因此比较对结束 pairing_iterator 为真。
如果底层迭代器是一个前向迭代器,我可以在每次取消引用时简单地读取该对,并在增量时简单地前进两次。但是使用输入迭代器我只能读取一次。
我是在重新发明一个已经存在于某个地方的轮子吗?我在 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;
};
第二个想法移除了exactly one dereference限制,但是又丑又奇怪:
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;
};
我可能犯了几个错误,但希望这足以描述这些概念。
关于c++ - 我如何编写一个迭代器包装器来组合来自底层迭代器的顺序值组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11424565/