C++ 如何创建特定的std::vector迭代器?
我正在从事一个设计非常糟糕的项目,我偶然发现了这种数据结构:C++ 如何创建特定的std::vector迭代器?,c++,templates,vector,iterator,C++,Templates,Vector,Iterator,我正在从事一个设计非常糟糕的项目,我偶然发现了这种数据结构: class OldBagOfData { public: std::vector< BaseClass* > baseDatas; std::vector< Derived1* > derived1Datas; std::vector< Derived2* > derived2Datas; std::vector< Derived3* > derived
class OldBagOfData
{
public:
std::vector< BaseClass* > baseDatas;
std::vector< Derived1* > derived1Datas;
std::vector< Derived2* > derived2Datas;
std::vector< Derived3* > derived3Datas;
std::vector< Derived4* > derived4Datas;
}
classoldbagofdata
{
公众:
std::vectorbaseDatas;
std::vectorDerived1数据;
std::vectorDerived2数据;
std::vectorDerived3数据;
std::vectorDerived4数据;
}
更新类的方法使用了大量的if/else条件(几十个),并且成员是可修改的(除此之外,它使用的是指针而不是实例),即使我们只读取数据
我已经通过使用通用函数和模板简化了代码:
class CurrentBagOfData
{
private:
std::vector< BaseClass* > genericContainer;
Template< typename DataType>
std::vector< DataType* > getData( datatype IDtype);
public:
std::vector< BaseClass* > getbaseDatas(); /* = getData<Base>("base") */
std::vector< Derived1* > getDerived1Datas(); /* = getData<Derived1>("derived1") */
std::vector< Derived2* > getDerived2Datas(); /* = getData<Derived2>("derived2") */
std::vector< Derived3* > getDerived3Datas(); /* = getData<Derived3>("derived3") */
std::vector< Derived4* > getDerived4Datas(); /* = getData<Derived4>("derived4") */
}
类CurrentBagOfData
{
私人:
std::vectorgenericContainer;
模板
std::vectorgetData(DataType IDtype);
公众:
std::vectorgetbaseDatas();/*=getData(“基”)*/
std::vectorgetderived1data();/*=getData(“Derived1”)*/
std::vectorgetDerived2Datas();/*=getData(“Derived2”)*/
std::vectorgetderived3data();/*=getData(“Derived3”)*/
std::vectorgetderived4data();/*=getData(“Derived4”)*/
}
但是,由于我只读取数据并对新输入排队,因此我希望使用迭代器:
// This loop is forbidden because obod.getDerived1Datas() is a temporary object
for( std::vector<Derived1*>::iterator it = obod.getDerived1Datas().begin();
it != obod.getDerived1Datas().end(); i++)
{
/* processing *it */
}
//What I want to do :
for( std::vector<Derived1*>::iteratorDerived1 it = obod.begin(); it != obod.end(); i++)
{
// it iterate over every Derived1 datas in the generic container
/* processing *it */
}
//禁止此循环,因为obod.getderived1data()是临时对象
对于(std::vector::iterator it=obod.getderived1data().begin();
it!=obod.getderived1data().end();i++)
{
/*处理它*/
}
//我想做的是:
对于(std::vector::iterateOrderived1 it=obod.begin();it!=obod.end();i++)
{
//它迭代泛型容器中的每个Derived1数据
/*处理它*/
}
如何创建std::vector::IterateOrderivedx?欢迎对我的设计提出任何其他建议。您可以在for循环之前保留函数调用的返回 此外,每次迭代都要调用end()方法,这可能会很昂贵 对于迭代器,pos增量比预增量更昂贵
std::vector<Derived1*> tmp = obod.getDerived1Datas();
for( std::vector<Derived1*>::iterator it = tmp.begin(), ed = tmp.end(); it != ed; ++i)
{
/* processing *it */
}
std::vector tmp=obod.getderived1data();
对于(std::vector::iterator it=tmp.begin(),ed=tmp.end();it!=ed;++i)
{
/*处理它*/
}
您不能(据我所知)向std::vector
类添加新成员。但是,您可以将其子类化,以便定义自己的迭代器
另一方面,您可以向CustomBagOfData
类添加一些新方法,例如:
public:
std::vector<Derived1*>::iterator getDerived1Begin() {
return getDerived1Datas().begin()
}
// And the same for getDerived1End
公共:
std::vector::迭代器getDerived1Begin(){
返回getDerived1Datas().begin()
}
//getDerived1End也是如此
然而,尽管不知道如何实现
DefinedN
类,我还是建议去掉那些幻数(Derived1,Derived2,…),并用参数做一些更优雅的事情。我发现了一种使用模板迭代器的方法。不幸的是,它会增加很多开销,因此我不确定是否会使用它:
#include <iostream>
#include <vector>
typedef std::string datatype ;
class BaseClass{
public:
BaseClass():type("base"){}
datatype type;
};
class Derived1 : public BaseClass{
public:
Derived1(){ type= "derived1"; }
};
class Derived2 : public BaseClass{
public:
Derived2(){ type ="derived2"; }
};
class Derived3 : public BaseClass{
public:
Derived3(){ type ="derived3"; }
};
class Derived4 : public BaseClass{
public:
Derived4(){ type ="derived4"; }
};
class CurrentBagOfData
{
private:
template< typename DataType>
std::vector< DataType* > getData( datatype IDtype)
{
std::vector< DataType* > output;
for(int i=0; i< genericContainer.size(); i++)
{
if(genericContainer[i]->type == IDtype)
{
output.push_back( (DataType*) genericContainer[i]);
}
}
return output;
}
public:
// Begin of the specialized container
template< class DataType>
std::vector< BaseClass* >::iterator begin()
{
std::vector< BaseClass* >::iterator it = genericContainer.begin();
datatype type = DataType().type;
while( it != genericContainer.end() && (*it)->type != type )
{
it++;
}
return it;
}
// End of the specialized container
template< class DataType>
std::vector< BaseClass* >::iterator end()
{
std::vector< BaseClass* >::iterator it = genericContainer.begin();
std::vector< BaseClass* >::iterator output = it;
datatype type = DataType().type;
while( it!= genericContainer.end() )
{
it++;
if( it!= genericContainer.end() && (*it)->type == type )
{
output = it;
}
}
return output;
}
// Iterate over a certain type of elements in the container
template< class DataType>
void gen( std::vector<BaseClass*>::iterator &it)
{
const std::vector< BaseClass* >::iterator e = this->genericContainer.end();
// Mandatory increment
if(it!= e )
it++;
// Loop until next DataType elem
datatype type = DataType().type;
while( it!= e && (*it)->type != type )
{
it++;
}
}
std::vector< BaseClass* > getbaseDatas(){ return getData<BaseClass>("base"); }
std::vector< Derived1* > getDerived1Datas(){ return getData<Derived1>("derived1"); }
std::vector< Derived2* > getDerived2Datas(){ return getData<Derived2>("derived2"); }
std::vector< Derived3* > getDerived3Datas(){ return getData<Derived3>("derived3"); }
std::vector< Derived4* > getDerived4Datas(){ return getData<Derived4>("derived4"); }
std::vector< BaseClass* > genericContainer;
};
int main()
{
// Object
CurrentBagOfData cbod;
cbod.genericContainer.push_back(new(BaseClass));
cbod.genericContainer.push_back(new(Derived1));
cbod.genericContainer.push_back(new(Derived3));
cbod.genericContainer.push_back(new(Derived2));
cbod.genericContainer.push_back(new(Derived1));
cbod.genericContainer.push_back(new(Derived4));
cbod.genericContainer.push_back(new(Derived3));
cbod.genericContainer.push_back(new(Derived3));
// Loop on Derived4 object, using the original method
std::vector< Derived4* > o = cbod.getDerived4Datas();
for (int i=0; i < o.size(); i++ )
{
std::cout << o[i]->type << std::endl;
}
std::cout << std::endl;
// Loop on Derived3 objects, with custom iterators.
std::vector< BaseClass* >::iterator it;
for( it = cbod.begin< Derived3 >(); it <= cbod.end< Derived3 >(); cbod.gen< Derived3 >(it) )
{
std::cout << (*it)->type << std::endl;
}
}
#包括
#包括
typedef std::字符串数据类型;
类基类{
公众:
BaseClass():类型(“base”){}
数据类型;
};
派生类1:公共基类{
公众:
Derived1(){type=“Derived1”}
};
派生类2:公共基类{
公众:
Derived2(){type=“Derived2”}
};
派生类3:公共基类{
公众:
Derived3(){type=“Derived3”}
};
派生类4:公共基类{
公众:
Derived4(){type=“Derived4”}
};
类CurrentBagOfData
{
私人:
模板
std::vectorgetData(数据类型IDtype)
{
std::vector输出;
对于(int i=0;itype==IDtype)
{
output.push_back((数据类型*)genericContainer[i]);
}
}
返回输出;
}
公众:
//专用容器的开头
模板<类数据类型>
std::vector::迭代器begin()
{
std::vector::迭代器it=genericContainer.begin();
数据类型类型=数据类型().type;
while(it!=genericContainer.end()&&(*it)->type!=type)
{
it++;
}
归还它;
}
//专用容器的末尾
模板<类数据类型>
std::vector::迭代器end()
{
std::vector::迭代器it=genericContainer.begin();
std::vector::迭代器输出=it;
数据类型类型=数据类型().type;
while(it!=genericContainer.end())
{
it++;
if(it!=genericContainer.end()&&(*it)->type==type)
{
输出=it;
}
}
返回输出;
}
//迭代容器中特定类型的元素
模板<类数据类型>
voidgen(std::vector::iterator&it)
{
const std::vector::迭代器e=this->genericContainer.end();
//强制增量
如果(it!=e)
it++;
//循环直到下一个数据类型elem
数据类型类型=数据类型().type;
while(it!=e&(*it)->type!=type)
{
it++;
}
}
std::vectorgetbaseDatas(){return getData(“base”);}
std::vectorgetderived1data(){return getData(“Derived1”);}
std::vectorgetDerived2Datas(){return getData(“Derived2”);}
std::vectorgetDerived3Datas(){return getData(“Derived3”);}
std::vectorgetderived4data(){return getData(“Derived4”);}
std::vectorgenericContainer;
};
int main()
{
//反对
当前BagofData cbod;
cbod.genericContainer.push_back(新的(基类));
cbod.genericContainer.push_