Reputation: 14869
I have a class graph
which has a member:
std::vector<std::unique_ptr<layer>> _layers;
I understand that the nature of std::unique_ptr
is to be non-copyable.
My graph::graph(const graph & rhs);
copy constructor produces a compilation error, because my ordinary implementation violates the nature of std::unique_ptr
.
graph::graph(const graph & rhs)
: _layers(rhs._layers) {}
If I do a std::move
then I will be violating the constness of param rhs
, which is not what I want.
I know I can make deep copies (e.g., create new unique pointers for each object stored in rhs._layers
) but is there some elegant way of doing this, other than iterating each item in rhs._layers
and allocating a new unique pointer?
gcc/g++ is c++11 not c++14
My current solution is deep copying the objects and allocating new pointers:
graph::graph(const graph & rhs)
{
for (const auto & ptr : rhs._layers)
_layers.emplace_back(std::unique_ptr<layer>(new layer(*ptr)));
}
Upvotes: 1
Views: 2298
Reputation: 4376
The most elegant solution would use the STL:
graph::graph(const graph & rhs)
{
_layers.reserve(rhs._layers.size());
std::transform(
std::begin(rhs._layers),
std::end(rhs._layers),
std::back_inserter(_layers),
[](const std::unique_ptr<layer>& uptr) {
return std::unique_ptr<layer>{uptr ? new layer{*uptr} : nullptr};
});
}
std::transform
, std::back_inserter
Upvotes: 7
Reputation: 5145
You can't make a copy but you can make a move constructor:
graph::graph(graph && rhs)
You should be able to move the _layers
vector in there and then you should be able to move graph
instances.
If this is not what you want then you will have to abandon the use of unique_ptr
or add a layer of indirection to the _layers
vector if that can be shared among graph instances.
Edit: An alternative solution would be to not use pointers in the vector at all but emplace the instances into the vector directly. This way the vector would be copied with all the contents naturally.
Upvotes: 0
Reputation: 86
You can also review the possibility to use the vector of std::shared_ptr instead of std::unique, in this case you can avoid real copying
Upvotes: 1