看看我的代码:
#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
?
总结一下:如果参数列表中的迭代器指向原始列表的第三个元素,我还希望克隆的迭代器指向第三个元素克隆名单。
答案 0 :(得分:3)
在您的代码中,您可以使用:
auto tempIt = std::next(tempList.begin(), std::distance(origList.begin(), it));
或者,当您使用std::vector
auto tempIt = tempList.begin() + (it - origList.begin());
请注意,您必须通过(const)引用传递origList
,否则std::distance(origList.begin(), it));
将是UB,因为迭代器不属于同一范围。