简体   繁体   English

克隆指针向量,是否可以以某种方式克隆迭代器?

[英]Cloning a vector of pointers, can I clone an iterator somehow too?

Have a look at my code: 看一下我的代码:

#include<vector>
#include<algorithm>
#include<iostream>
using namespace std;

class AbstractBase
{
protected:
    int ident;
public:
    virtual void add() = 0;   
    int getIdent()const {return ident;}
    virtual ~AbstractBase(){};
    virtual AbstractBase* clone()const =0;
};

class Derived1 :public AbstractBase
{    
public:
    Derived1(int i)
    {
        ident=i;
    };
    virtual void add() override
    {
        ident+=1;
    }
    virtual AbstractBase* clone() const override
    {
        return new Derived1 (*this);
    }
};

class Derived2 :public AbstractBase
{    
public:
    Derived2(int i)
    {
        ident=i;
    }
    virtual void add() override
    {
        ident+=2;
    }
    virtual AbstractBase* clone() const override
    {
        return new Derived2(*this);
    }
};

class cloneFunctor
{
public:
    AbstractBase* operator() (AbstractBase* a) const
    {
        return a->clone();
    }
};

struct IdentCompare
{
    bool operator()(AbstractBase* f)
    {
        return f->getIdent() >5;
    }
};

void WorkWithClonedVector(vector<AbstractBase*>origList,vector<AbstractBase*>::iterator it)
{
    vector<AbstractBase*> tempList;
    transform(origList.begin(),origList.end(),back_inserter(tempList),cloneFunctor());
    //NEED TO FIND ITERATOR AGAIN-->ANY OTHER OPTION?
    vector<AbstractBase*>::iterator tempIt=find_if(tempList.begin(),tempList.end(),IdentCompare());
    (*tempIt)->add();
    cout<<"local list:\n";
    for(unsigned int i=0;i<tempList.size();++i)
    {
        cout<<"Element "<<(i+1)<<": "<<tempList[i]->getIdent()<<'\n';
        delete tempList[i];
    }
    cout<<"Original Iterator still pointing to: "<<(*it)->getIdent()<<'\n';
    tempList.clear();
}


int main()
{
    Derived1 d1(1);
    Derived1 d1b(2);
    Derived2 d2(7);
    Derived2 d2b(5);
    vector<AbstractBase*> List;
    List.push_back(&d1);
    List.push_back(&d1b);
    List.push_back(&d2);
    List.push_back(&d2b);
    vector<AbstractBase*>::iterator iter = find_if(List.begin(),List.end(),IdentCompare());
    WorkWithClonedVector(List,iter);
    cout<<"Original List not changed:\n";
    for(unsigned int i=0;i<List.size();++i)
    {
        cout<<"Element "<<(i+1)<<": "<<List[i]->getIdent()<<'\n';
    }
}

As you can see I successfully managed to clone a vector<AbstractBase*> within WorkWithClonedVector in order to safely work on the temporary list without changing anything in the original List. 如您所见,我成功地在WorkWithClonedVectorvector<AbstractBase*> ,以便安全地在临时列表上工作而无需更改原始List中的任何内容。 I was wondering if there is any possibility to "clone" the iterator in the parameter list of WorkWithClonedVector too, so I don't need to use find_if twice? 我想知道是否也有可能“复制” WorkWithClonedVector的参数列表中的迭代器,所以我不需要两次使用find_if吗? To summarize it: if the iterator in the parameter list is pointing to the third element of the original list, I'd also like the cloned iterator to point to the third element of the cloned list. 总结一下:如果参数列表中的迭代器指向原始列表的第三个元素,我还希望克隆的迭代器指向克隆列表的第三个元素。

In your code, you may use instead: 在代码中,您可以改为使用:

auto tempIt = std::next(tempList.begin(), std::distance(origList.begin(), it));

or, as you work with std::vector 或者,当您使用std::vector

auto tempIt = tempList.begin() + (it - origList.begin());

Demo 演示

Note that you have to pass origList by (const)reference, else std::distance(origList.begin(), it)); 注意,您必须通过(const)reference传递origList ,否则传递std::distance(origList.begin(), it)); would be UB as the iterator won't belong to the same range. 将为UB,因为迭代器不会属于同一范围。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM