I have a class, which supports cloning (via method clone
). I have a bunch of its instances in a vector of std::unique_ptr
.
Now, I want to create an std::set
of same smart pointers from the above vector, ideally during its construction. The obvious design is as following:
#include <memory>
#include <set>
#include <vector>
class A
{
public:
/// type of itself
typedef A self;
A() = default;
A(const self& another) = default;
virtual ~A() = default;
std::unique_ptr<A> clone() const
{
return std::make_unique<A>();
}
};
class SetOfA
{
public:
SetOfA() = default;
// Here is the method I would like to improve
SetOfA(const std::vector<std::unique_ptr<A> >& data)
{
//do not like this loop, prefer this to be in initialization part?
for (const auto& d : data) {
set_of_a.insert(std::move(d->clone()));
}
}
private:
std::set<std::unique_ptr <A> > set_of_a;
};
But is there a way to avoid this for
loop in constructor and move the std::set
construction into initialization part?
If you can use Boost, here is a possible solution:
SetOfA(const std::vector<std::unique_ptr<A>>& data) :
set_of_a(
boost::make_transform_iterator(data.begin(), std::mem_fn(&A::clone)),
boost::make_transform_iterator(data.end(), std::mem_fn(&A::clone)))
{ }