Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/152.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何创建特定的std::vector迭代器?_C++_Templates_Vector_Iterator - Fatal编程技术网

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_