C++ 用作一维的多维向量的迭代器?
我有一个向量,看起来像这样:C++ 用作一维的多维向量的迭代器?,c++,c++11,vector,iterator,std,C++,C++11,Vector,Iterator,Std,我有一个向量,看起来像这样: std::vector<std::vector<MyClass>> myVector; (也就是说,存在多个维度的事实对于通过myVector循环的人来说是透明的) 我知道应该怎么做,有一个自定义的迭代器实现,它保存当前的索引,这样当一个向量没有更多的元素时,它会重置一个索引并增加另一个,这样它就可以开始遍历下一个向量,依此类推。但我一直在尝试编码这个想法,但似乎无法让它工作。有人知道我怎样才能做到这一点吗?或者更好,如果有任何开源项目有类
std::vector<std::vector<MyClass>> myVector;
(也就是说,存在多个维度的事实对于通过myVector循环的人来说是透明的)
我知道应该怎么做,有一个自定义的迭代器实现,它保存当前的索引,这样当一个向量没有更多的元素时,它会重置一个索引并增加另一个,这样它就可以开始遍历下一个向量,依此类推。但我一直在尝试编码这个想法,但似乎无法让它工作。有人知道我怎样才能做到这一点吗?或者更好,如果有任何开源项目有类似的实现
谢谢。完全可以定义自己的迭代器来隐藏遍历向量向量的所有细节,我编写了一些代码来告诉您这个想法,请注意,它需要更多的检查,但它基本上是有效的,并且给了您这个想法 您只需要编写所需的操作,就可以在其他代码(如不透明迭代器)中工作
template <typename T>
struct vector2d
{
public:
class iterator
{
public:
using vector_type = std::vector<std::vector<T>>;
using first_level_iterator = typename std::vector<std::vector<T>>::iterator;
using second_level_iterator = typename std::vector<T>::iterator;
private:
vector_type& data;
first_level_iterator fit;
second_level_iterator sit;
public:
iterator(vector_type& data, bool begin) : data(data)
{
if (begin)
{
fit = data.begin();
sit = fit->begin();
}
else
{
fit = data.end();
}
}
inline bool operator!=(const iterator& other) const { return fit != other.fit || (fit != data.end() && sit != other.sit); }
inline const iterator& operator++() {
// don't go past end
if (fit == data.end())
return *this;
// increment inner iterator
++sit;
// if we reached the end of inner vector
if (sit == fit->end())
{
// go to next vector
++fit;
// if we reached end then don't reset sit since it would be UB
if (fit != data.end())
sit = fit->begin();
}
return *this;
}
T& operator*() const { return *sit; }
};
public:
std::vector<std::vector<T>> data;
iterator begin() { return iterator(this->data, true); }
iterator end() { return iterator(this->data, false); }
};
模板
结构向量2D
{
公众:
类迭代器
{
公众:
使用vector_type=std::vector;
使用第一级迭代器=typename std::vector::iterator;
使用第二级迭代器=typename std::vector::iterator;
私人:
向量类型和数据;
第一级迭代器拟合;
第二层迭代器sit;
公众:
迭代器(向量类型&数据,布尔开始):数据(数据)
{
如果(开始)
{
fit=data.begin();
sit=fit->begin();
}
其他的
{
fit=data.end();
}
}
内联布尔运算符!=(常量迭代器和其他)常量{return fit!=other.fit | |(fit!=data.end()&&sit!=other.sit);}
内联常量迭代器和运算符++(){
//不要走到尽头
if(fit==data.end())
归还*这个;
//增量内迭代器
++坐;
//如果我们到达内向量的末端
如果(sit==fit->end())
{
//转到下一个向量
++适合;
//如果我们到达终点,那么不要重置坐姿,因为这将是UB
if(fit!=data.end())
sit=fit->begin();
}
归还*这个;
}
T&运算符*()常量{return*sit;}
};
公众:
std::矢量数据;
迭代器begin(){返回迭代器(this->data,true);}
迭代器end(){返回迭代器(this->data,false);}
};
一个小测试:
int main() {
vector2d<int> data;
data.data.push_back(vector<int>());
data.data.push_back(vector<int>());
data.data.push_back(vector<int>());
for (int i = 1; i < 5; ++i)
{
data.data[0].push_back(i);
data.data[1].push_back(i*2);
data.data[2].push_back(i*3);
}
for (auto i : data)
{
cout << i << endl;
}
return 0;
}
intmain(){
矢量二维数据;
data.data.push_back(vector());
data.data.push_back(vector());
data.data.push_back(vector());
对于(int i=1;i<5;++i)
{
data.data[0]。推回(i);
data.data[1]。推回(i*2);
data.data[2]。推回(i*3);
}
用于(自动i:数据)
{
cout完全可以定义自己的迭代器来隐藏遍历向量向量的所有细节,我写了一些代码来告诉你这个想法,记住它应该需要更多的检查,但它基本上是有效的,并且给了你这个想法
您只需要编写所需的操作,就可以在其他代码(如不透明迭代器)中工作
template <typename T>
struct vector2d
{
public:
class iterator
{
public:
using vector_type = std::vector<std::vector<T>>;
using first_level_iterator = typename std::vector<std::vector<T>>::iterator;
using second_level_iterator = typename std::vector<T>::iterator;
private:
vector_type& data;
first_level_iterator fit;
second_level_iterator sit;
public:
iterator(vector_type& data, bool begin) : data(data)
{
if (begin)
{
fit = data.begin();
sit = fit->begin();
}
else
{
fit = data.end();
}
}
inline bool operator!=(const iterator& other) const { return fit != other.fit || (fit != data.end() && sit != other.sit); }
inline const iterator& operator++() {
// don't go past end
if (fit == data.end())
return *this;
// increment inner iterator
++sit;
// if we reached the end of inner vector
if (sit == fit->end())
{
// go to next vector
++fit;
// if we reached end then don't reset sit since it would be UB
if (fit != data.end())
sit = fit->begin();
}
return *this;
}
T& operator*() const { return *sit; }
};
public:
std::vector<std::vector<T>> data;
iterator begin() { return iterator(this->data, true); }
iterator end() { return iterator(this->data, false); }
};
模板
结构向量2D
{
公众:
类迭代器
{
公众:
使用vector_type=std::vector;
使用第一级迭代器=typename std::vector::iterator;
使用第二级迭代器=typename std::vector::iterator;
私人:
向量类型和数据;
第一级迭代器拟合;
第二级迭代器sit;
公众:
迭代器(向量类型&数据,布尔开始):数据(数据)
{
如果(开始)
{
fit=data.begin();
sit=fit->begin();
}
其他的
{
fit=data.end();
}
}
内联布尔运算符!=(常量迭代器和其他)常量{return fit!=other.fit | |(fit!=data.end()&&sit!=other.sit);}
内联常量迭代器和运算符++(){
//不要走到尽头
if(fit==data.end())
归还*这个;
//增量内迭代器
++坐;
//如果我们到达内向量的末端
如果(sit==fit->end())
{
//转到下一个向量
++适合;
//如果我们到达终点,那么不要重置坐姿,因为这将是UB
if(fit!=data.end())
sit=fit->begin();
}
归还*这个;
}
T&运算符*()常量{return*sit;}
};
公众:
std::矢量数据;
迭代器begin(){返回迭代器(this->data,true);}
迭代器end(){返回迭代器(this->data,false);}
};
一个小测试:
int main() {
vector2d<int> data;
data.data.push_back(vector<int>());
data.data.push_back(vector<int>());
data.data.push_back(vector<int>());
for (int i = 1; i < 5; ++i)
{
data.data[0].push_back(i);
data.data[1].push_back(i*2);
data.data[2].push_back(i*3);
}
for (auto i : data)
{
cout << i << endl;
}
return 0;
}
intmain(){
矢量二维数据;
data.data.push_back(vector());
data.data.push_back(vector());
data.data.push_back(vector());
对于(int i=1;i<5;++i)
{
data.data[0]。推回(i);
data.data[1]。推回(i*2);
data.data[2]。推回(i*3);
}
用于(自动i:数据)
{
cout一个非常小的范围类型:
template<class It>
struct range_t {
private:
It b, e;
public:
It begin() const { return b; }
It end() const { return e; }
decltype(auto) front() const { return *b; }
decltype(auto) back() const { return *std::prev(e); }
bool empty() const { return b==e; }
range_t without_front( std::size_t n = 1 ) const {
auto r = *this;
std::advance(r.b,n);
return r;
}
range_t without_back( std::size_t n = 1 ) const {
auto r = *this;
std::advance(r.e,std::ptrdiff_t(-n));
return r;
}
range_t(It s, It f):b(std::move(s)), e(std::move(f)) {}
range_t():b(), e() {}
};
template<class It>
range_t<It> range( It b, It e ) {
return {std::move(b), std::move(e)};
}
模板
结构范围{
私人:
它是b,e;
公众:
它的begin()常量{return b;}
It end()常量{return e;}
decltype(auto)front()常量{return*b;}
decltype(auto)back()常量{return*std::prev(e);}
bool empty()常量{返回b==e;}
不带前端的范围(标准::大小n=1)常数{
自动r=*这个;
标准:预付款(r.b,n);
返回r;
}
没有返回的范围(标准::大小n=1)常数{
自动r=*这个;
std::advance(r.e,std::ptrdiff_t(-n));
返回r;
}
范围t(It s,It f):b(std::move(s)),e(std::move(f)){
范围t():b(),e(){}
};
模板
范围\u t范围(It b、It e){
返回{std::move(b),std::move(e)};
}
使用范围执行此任务比使用迭代器容易得多
template<class Outer, class Inner>
struct stacked_range_t {
range_t<Outer> outer;
stacked_range_t()=default;
stacked_range_t( range_t<Outer> o ):outer(std::move(o)) {}
struct iterator {
private:
range_t<Outer> outer;
range_t<Inner> inner;
public:
iterator(
range_t<Outer> o,
range_t<Inner> i
):outer(std::move(o)), inner(std::move(i)) {}
iterator()=default;
friend auto mytie(iterator const& it) {
return std::tie( it.outer.begin(), it.inner.begin(), it.inner.end() );
}
friend bool operator==(iterator const& lhs, iterator const& rhs) {
return mytie(lhs)==mytie(rhs);
}
friend bool operator!=(iterator const& lhs, iterator const& rhs) {
return mytie(lhs)==mytie(rhs);
}
using difference_type = std::ptrdiff_t;
using value_type = typename std::iterator_traits<Inner>::value_type;
using pointer = typename std::iterator_traits<Inner>::pointer;
using reference = typename std::iterator_traits<Inner>::reference;
using iterator_category = std::input_iterator_tag;
reference operator*() const {
return *inner.begin();
}
pointer operator->() const {
return inner.begin().operator->();
}
iterator& operator++() {
using std::begin; using std::end;
inner = inner.without_front();
while (inner.empty())
{
outer = outer.without_front();
if (!outer.empty())
inner = range( begin(outer.front()), end(outer.front()) );
}
return *this;
}
iterator operator++(int) {
auto it = *this;
++*this;
return it;
}
};
iterator end() const {
return { range( outer.end(), outer.end() ), {} };
}
// a bit tricky:
iterator begin() const {
if (outer.empty()) return end();
auto rout = outer;
while( !rout.empty() ) {
using std::begin; using std::end;
auto rin = range( begin(rout.front()), end(rout.front()) );
if (!rin.empty())
return {std::move(rout), std::move(rin)};
rout = rout.without_front();
}
return end();
}
};
模板
结构堆叠\u范围\u t{
范围外;
堆叠的_范围_t()=默认值;
堆叠的范围:外部(std::move(o)){
结构迭代器{
私人:
范围外;
范围内;
公众:
迭代器(
射程,
射程
):外部(std::move(o)),内部(std::move(i)){}
迭代器()=默认值;
friend auto mytie(迭代器常量&it){
#include <stdio.h>
#include <vector>
template <typename V>
void f(V& v){
for(auto& e : v){
f(e);
}
printf("\n");
}
template <>
void f(int& v){
printf("%d ",v);
}
int main(){
std::vector<int> v1={1,2};
f(v1);
std::vector<std::vector<int> > v2={{3,4},{5,6,7}};
f(v2);
return 0;
};
for (auto& x : myVector | ranges::view::join)
{
foo(x); // x is an object of type MyClass&
}