克隆一个指针向量,我可以以某种方式克隆一个迭代器吗?

时间:2017-05-04 14:59:37

标签: c++ vector iterator clone

看看我的代码:

#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';
    }
}

正如您所看到的,我已成功设法克隆vector<AbstractBase*>中的WorkWithClonedVector,以便安全地处理临时列表而无需更改原始列表中的任何内容。我想知道是否有可能在WorkWithClonedVector的参数列表中“克隆”迭代器,所以我不需要两次使用find_if? 总结一下:如果参数列表中的迭代器指向原始列表的第三个元素,我还希望克隆的迭代器指向第三个元素克隆名单。

1 个答案:

答案 0 :(得分:3)

在您的代码中,您可以使用:

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

或者,当您使用std::vector

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

Demo

请注意,您必须通过(const)引用传递origList,否则std::distance(origList.begin(), it));将是UB,因为迭代器不属于同一范围。