gpt4 book ai didi

c++ - 调整自定义迭代器以便(a?)reverse_iterator 可以翻转它的输出

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:34:35 25 4
gpt4 key购买 nike

最近,用户@Mooing Duck 设计了concatenated_range ,一个优雅的自定义迭代器,解决了“链接”两个迭代器的问题,一切都在幕后。

它非常适合预期用途:

auto range0=concatenate_ranges(x,x+i-1,x+i,x+a5+1);
a6=foo(range0.first,range0.second);

现在,我想通过执行(示例 #2)来调整它:

auto range0=concatenate_ranges(x+a5+1,x+i-1,x+i+1,x+n);
a6=foo(std::reverse_iterator<float*>(range0.second),std::reverse_iterator<float*>(range0.first));

不用说,编译器不高兴。替代方案(不确定此处的顺序是否正确):

auto range0=concatenate_ranges(std::reverse_iterator<float*>(x+n),x+i+1,x+i-1,std::reverse_iterator<float*>(x+a5[i]+1));
a6=foo(range0.first,range0.second);

也不是理所当然的 :(。

我的问题是:我如何调整 concatenate_ranges() 以便它的输出可以是馈入 std::reverse_iterator(如上面的第二个示例)。还有,我不介意使用 boost:: 如果它使事情变得更容易。

编辑:

用户@Jack 报告原始答案中的链接没有为他显示代码。我不知道这个问题有多普遍,所以为了清楚起见,我重现了我在此处引用的代码(请参阅原始答案的解释):

#include <boost/iterator/iterator_facade.hpp>
#include <iterator>
#include <cassert>

template<class base>
class concatenated_range_iterator
: public boost::iterator_facade<
concatenated_range_iterator<base>,
typename std::iterator_traits<base>::value_type,
typename std::iterator_traits<base>::iterator_category,
typename std::iterator_traits<base>::reference,
typename std::iterator_traits<base>::difference_type
>
{
public:
typedef typename std::iterator_traits<base>::iterator_category iterator_category;
typedef typename std::iterator_traits<base>::value_type value_type;
typedef typename std::iterator_traits<base>::difference_type difference_type;
typedef typename std::iterator_traits<base>::pointer pointer;
typedef typename std::iterator_traits<base>::reference reference;

concatenated_range_iterator() = default;
concatenated_range_iterator(bool begin, base begin1, base end1, base begin2, base end2)
:current(begin?begin1:end2), end_first(end1), begin_second(begin2), in_first(begin)
{}

reference dereference() {return *current;}
reference dereference() const {return *current;}
bool equal(const concatenated_range_iterator& rhs) const {
assert(end_first==rhs.end_first);
assert(begin_second==rhs.begin_second);
return in_first==rhs.in_first && current==rhs.current;
}
void increment() {
++current;
if (in_first) {
if (current==end_first) {
current = begin_second;
in_first = false;
}
}
}
void decrement() {
if (!in_first) {
if (current==begin_second) {
current = end_first;
in_first = true;
}
}
--current;
}
void advance(difference_type n) {
if (n>=0) {
if (in_first) {
difference_type safe = end_first-current;
if (safe <= n) {
current = begin_second;
n -= safe;
in_first = false;
}
}
} else {
if (!in_first) {
difference_type safe = current-begin_second;
if (safe <= n) {
current = end_first;
n += safe;
in_first = true;
}
}
}
current += n;
}
difference_type distance_to(const concatenated_range_iterator& rhs) const {
assert(end_first==rhs.end_first);
assert(begin_second==rhs.begin_second);
if (in_first) {
if (rhs.in_first)
return rhs.current-current;
else
return rhs.current-begin_second + end_first-current;
} else {
if (rhs.in_first)
return rhs.current-end_first + begin_second-current;
else
return rhs.current-current;
}
}
protected:
base current;
base end_first;
base begin_second;
bool in_first;
};
template<class base>
std::pair<concatenated_range_iterator<base>,concatenated_range_iterator<base>>
concatenate_ranges(base first1, base end1, base first2, base end2)
{
return std::pair<concatenated_range_iterator<base>,concatenated_range_iterator<base>>(
concatenated_range_iterator<base>(true, first1, end1, first2, end2),
concatenated_range_iterator<base>(false, first1, end1, first2, end2)
);
}


#include <vector>
#include <iostream>
int main() {
std::vector<int> vars = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};

auto range = concatenate_ranges(vars.begin(), vars.begin()+4, vars.begin()+5, vars.end());
for(auto iter=range.first; iter!=range.second; ++iter)
std::cout << *iter << ' ';
}

最佳答案

您正在实例化 reverse_iterator模板不正确。尝试

auto fst = std::reverse_iterator<decltype(range0.second)>(range0.second);
auto snd = std::reverse_iterator<decltype(range0.first)>(range0.first);

为了使类型更明确:

typedef std::vector<int>::iterator VI;
typedef concatenated_range_iterator<VI> CRVI;
typedef std::pair<CRVI, CRVI> CRVIrange;
CRVIrange range0 = concatenate_ranges(vars.begin(), vars.begin()+2,
vars.begin()+5, vars.end());

typedef std::reverse_iterator<CRVI> RCRVI;
RCRVI fst = RCRVI(range0.second);
RCRVI snd = RCRVI(range0.first);

我不想写下类似 std::pair<std::reverse_iterator<concatenated_range_iterator<std::vector<int>::iterator>>,std::reverse_iterator<concatenated_range_iterator<std::vector<int>::iterator>>> 的东西!

关于c++ - 调整自定义迭代器以便(a?)reverse_iterator 可以翻转它的输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23814048/

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