#include <vector>
#include <algorithm>
#include <iostream>
#include <memory>
class AbstractBase
{
protected:
int ident;
public:
AbstractBase(int id) : ident(id) {}
virtual ~AbstractBase() {}
virtual std::unique_ptr<AbstractBase> clone() const = 0;
virtual void add() = 0;
int getIdent()const {return ident;}
};
class Derived1 : public AbstractBase
{
public:
Derived1(int i) : AbstractBase(i) {}
void add() override { ident += 1; }
std::unique_ptr<AbstractBase> clone() const override
{
return std::make_unique<Derived1>(*this);
}
};
class Derived2 : public AbstractBase
{
public:
Derived2(int i) : AbstractBase(i) {}
void add() override { ident+=2; }
std::unique_ptr<AbstractBase> clone() const override
{
return std::make_unique<Derived2>(*this);
}
};
class cloneFunctor
{
public:
std::unique_ptr<AbstractBase> operator() (const AbstractBase* a) const
{
return a->clone();
}
};
struct IdentCompare
{
bool operator()(const AbstractBase* f) const
{
return f->getIdent() > 5;
}
};
void WorkWithClonedVector(const std::vector<AbstractBase*>& origList, std::vector<AbstractBase*>::const_iterator it)
{
std::vector<std::unique_ptr<AbstractBase>> tempList;
std::transform(origList.begin(),origList.end(),back_inserter(tempList),cloneFunctor());
auto tempIt = std::next(tempList.begin(), std::distance(origList.begin(), it));
(*tempIt)->add();
std::cout << "local list:\n";
int i = 1;
for(const auto& cloned : tempList)
{
std::cout << "Element " << i << ": " << cloned->getIdent() << '\n';
++i;
}
std::cout << "Original Iterator still pointing to: " << (*it)->getIdent() << '\n';
}
int main()
{
Derived1 d1(1);
Derived1 d1b(2);
Derived2 d2(7);
Derived2 d2b(5);
std::vector<AbstractBase*> List = {&d1, &d1b, &d2, &d2b};
auto iter = std::find_if(List.begin(), List.end(), IdentCompare());
WorkWithClonedVector(List, iter);
std::cout << "Original List not changed:\n";
int i = 1;
for(const auto& derived : List)
{
std::cout << "Element " << i << ": " << derived->getIdent() << '\n';
}
}