创建迭代器以C++返回 std::p air 的容器
Create Iterator to C++ container that returns a std::pair
我正在尝试在C++中实现一个容器,该容器使用平面数组来存储数据,但成对迭代该数据。 现在我可以轻松地更改实现,以便容器包含std::pair
向量,但是我想遍历从元素 0 或元素 1 开始的对。
为了说明我想要实现的目标,如果我的基础数组如下所示:1,2,3,4,5,6,7,8
我想定义两个迭代器,一个返回对:(1,2), (3,4), (5,6), (7,8)以及返回货币对的第二个迭代器:(2,3), (4,5), (6,7)
这是否可能同时仍然允许迭代器的元素作为底层数组的引用?
可以编写自己的迭代器,该迭代器遍历元素。以下问题显示了有关如何完成此操作的一些解释:C++中的自定义迭代器。
然后,您可以将所需的值作为 std::p air 返回,并迭代到下一个元素对(通过将计数器递增 2)。
Boost 库具有迭代器适配器,允许您包装其他迭代器类型并更改或调整其功能。以下是您可以将其用于您的目的的方法:
#include <boost/iterator/iterator_adaptor.hpp>
#include <vector>
struct iterator :
public boost::iterator_adaptor<
iterator, // the name of our class, see docs for details
std::vector<int>::iterator, // underlying base iterator
std::pair<int&, int&>, // our value type
boost::forward_traversal_tag // the category you wish to give it
>
{
// need this to convert from vector::iterator to ours
explicit iterator(std::vector<int>::iterator i)
: iterator::iterator_adaptor_(i) {}
value_type operator*()
{
return value_type(
*base_reference(),
*(base_reference()+1)
);
}
};
用法示例:
std::vector<int> v {1,2,3,4};
iterator it(v.begin());
++it;
(*it).first = 0; // TODO: operator->
(*it).second = 0;
for (int i : v) std::cout << i << ' '; // prints 1 0 0 4
您还需要覆盖比较以正确处理最终条件等。 希望有帮助。
只是想我已经在我的代码中投入了我实际使用的东西。 我不想按照@jrok的建议使用 boost,但他们答案中std::pair<int&, int&>
的类型给了我一个需要什么的提示。
下面是我构造的类,它使用两个迭代器。 返回从基础数据中的偶数索引开始的对的RepeatIterator
,以及返回从奇数索引开始的对的SpacerIterator
。
class RepeatArray {
typedef std::vector<int> storage_t;
public:
class RepeatIterator {
public:
typedef RepeatIterator self_t;
typedef int value_t;
typedef int& reference_t;
typedef int* pointer_t;
typedef std::pair<reference_t, reference_t> return_t;
RepeatIterator(storage_t::iterator input) : current_pos(input){}
return_t operator *() {
return return_t(*(current_pos), *(current_pos + 1 ));
}
self_t operator++() { self_t i = *this; current_pos += 2; return i; }
self_t operator++(int junk) { current_pos+=2; return *this; }
bool operator==(const self_t& rhs) { return current_pos == rhs.current_pos; }
bool operator!=(const self_t& rhs) { return current_pos != rhs.current_pos; }
bool operator<(const self_t& rhs) { return current_pos < rhs.current_pos; }
bool operator<=(const self_t& rhs) { return current_pos <= rhs.current_pos; }
bool operator>(const self_t& rhs) { return current_pos > rhs.current_pos; }
bool operator>=(const self_t& rhs) { return current_pos >= rhs.current_pos; }
private:
storage_t::iterator current_pos;
};
class SpacerIterator {
public:
typedef SpacerIterator self_t;
typedef int value_t;
typedef int& reference_t;
typedef int* pointer_t;
typedef std::pair<reference_t, reference_t> return_t;
SpacerIterator(storage_t::iterator input) : current_pos(input){}
return_t operator *() {
return return_t(*(current_pos), *(current_pos + 1 ));
}
self_t operator++() { self_t i = *this; current_pos += 2; return i; }
self_t operator++(int junk) { current_pos+=2; return *this; }
bool operator==(const self_t& rhs) { return current_pos == rhs.current_pos; }
bool operator!=(const self_t& rhs) { return current_pos != rhs.current_pos; }
bool operator<(const self_t& rhs) { return current_pos < rhs.current_pos; }
bool operator<=(const self_t& rhs) { return current_pos <= rhs.current_pos; }
bool operator>(const self_t& rhs) { return current_pos > rhs.current_pos; }
bool operator>=(const self_t& rhs) { return current_pos >= rhs.current_pos; }
private:
storage_t::iterator current_pos;
};
void add(int start, int end) {
positions.push_back(start);
positions.push_back(end);
}
void dump() {
for (auto i : positions) {
std::cout <<i<<",";
}
std::cout <<std::endl;
}
RepeatIterator repeatBegin(){return RepeatIterator(positions.begin());}
RepeatIterator repeatEnd(){return RepeatIterator(positions.end());}
SpacerIterator spacerBegin(){return SpacerIterator(positions.begin() + 1);}
SpacerIterator spacerEnd(){return SpacerIterator(positions.end() - 1);}
protected:
storage_t positions;
};
然后使用clang++ -std=c++0x -o testRepeatArray RepeatArray.cpp
编译的tesing程序
int main() {
RepeatArray r = RepeatArray();
r.add(1,3);
r.add(7,12);
std::cout<<"original:"<<std::endl;
r.dump();
std::cout << "Testing Repeat iterator:"<<std::endl;
for (RepeatArray::RepeatIterator it2 = r.repeatBegin(); it2 != r.repeatEnd(); ++it2) {
std::cout << (*it2).first <<","<< (*it2).second << std::endl;
}
std::cout << "Testing Spacer iterator:"<<std::endl;
for (RepeatArray::SpacerIterator it3 = r.spacerBegin(); it3 != r.spacerEnd(); ++it3) {
std::cout << (*it3).first <<","<< (*it3).second << std::endl;
}
std::cout<<"Testing modification:"<<std::endl;
RepeatArray::RepeatIterator it = r.repeatBegin();
(*it).first = 0;
(*it).second = 123;
r.dump();
return 0;
}
相关文章:
- 为什么 const std::p air<K,V>& 在 std::map 上基于范围的 for 循环不起作用?
- C++:无法使用 "=" 运算符更改 std::p air 的值
- 如何在创建自定义迭代器时获得 std::p air 的第一个和第二个?
- 使用 std::p air 进行返回值优化
- 标准::在双类和类的 std::p air 上更大
- 为什么 std::p air 的大小与其元素的大小之和不同?
- 像 std::list<std::p air<string, string>> 这样的结构在返回时会被复制吗?
- 查找 std::vector 中的最小值和最大值 std::p air
- 地图是否将元素存储为 std::p air?
- std::p air 会破坏其动态分配的对象吗?
- 如何在 std::p air 中使用 System::Guid 和自定义枚举?
- boost::mpl 不使用(甚至不兼容)std::p air 的原因是什么?
- 在具有 std::p air 键和值的映射中添加 b2vec2
- 无法访问 std::p air 的成员秒
- 如何在 std::map 中从 std::vector of std::p air 中获取输入?
- 二进制">>":未找到采用类型为"std::p air<int,int>"的右操作数的运算符
- 通过预处理器创建 std::p air<std::string,some_enum>
- 类中的编译器错误,数据类型为 typedef map<std::string,std::p air<std::string,vector<int>>> MapPai
- 如何使用 swig 类型映射将 std::vector<std::p air<std::string, int> > 从 java 返回到 c++
- 从"void"转换为非标量类型"std::p air<std::basic_string<字符,std::char_traits<char>