vector deep copy using a functor or lambda

2019-09-10 07:26发布

问题:

I am trying to make deep copies of vectors of std::shared_ptr. Unfortunately I can't use objects, as most of those pointers are to polymorphic objects.

I've tried using the clone method adapted to std::shared_ptr:

std::shared_ptr<Action> Clone ( )
{
  return std::make_shared<Action>( *this );
}

But I am still running into problems. So, I was wondering (can't remember where I've seen it) how can I copy the contents of one vector into another, by using a function or a lambda that performs the actual deep copy.

Let me rephrase, I don't want just the pointers, I want a copy of the pointed objects too. The typical assignment

operator=

for std::vector appears to copy only the pointers as one would normally expect.

I'm using GCC 4.8 with C++11 in case it can offer any more elegant or minimalistic approach.

The actual purpose is so that copy constructors of classes that have those vectors, provide non-shared objects but same or different pointers:

class State
{
public:
  State ( const State & rhs )
  {
    // Deep copy Actions here?
  }


private:
  std::vector<std::shared_ptr<Action>> _actions;
};

Many thanks to anyone who can help!

回答1:

To deep-copy/clone a type-erased type the cloning function needs to be virtual

struct Action {
    virtual std::shared_ptr<Action> clone() const =0;
};
struct Paste : public Action {  
    virtual std::shared_ptr<Action> clone() const 
    {return std::make_shared<Paste>(*this);}
};

Once you have that, then you can use transform and a simple lambda.

std::vector<std::shared_ptr<Action>> ActionList = {...};

auto cloner = [](const std::shared_ptr<Action>& ptr) 
    -> std::shared_ptr<Action> 
    {return ptr->clone();};

std::vector<std::shared_ptr<Action>> Copy;
std::transform(ActionList.begin(), ActionList.end(), std::back_inserter(Copy), cloner);