将 initializer_list 个指针转换为 unique_ptr 个向量
Convert initializer_list of pointers to vector of unique_ptr
我创建了这个 class,它代表一组形状:
class CompoundShape : public Shape {
private:
std::vector<std::unique_ptr<Shape>> shapes;
public:
CompoundShape(std::initializer_list<Shape *> shapes) : shapes(shapes) {}
void draw() {
for_each(shapes.begin(), shapes.end(), [](auto &shape) { shape->draw(); });
}
};
classShape
还有另一个childclass,SimpleShape
。理想情况下,我想像这样初始化一个 CompoundShape
,而不必担心之后释放指向形状的指针:
CompoundShape shape = {
new SimpleShape(...),
new SimpleShape(...),
new CompoundShape{...},
...
}
我认为唯一的问题是在 CompoundShape
构造函数中,我尝试在其中执行 shapes(shapes)
这当然行不通,因为 std::vector<std::unique_ptr<Shape>>
不能用 std::initializer_list<Shape *> shapes
.
初始化
实现此转换的最佳方式是什么?
遗憾的是我们无法使用 std::initializer_list<std::unique_ptr<Shape>>
。
您仍然可以使用带有 2 个迭代器的 vector 构造函数来进行(不是那么明确的)转换:
CompoundShape(std::initializer_list<Shape *> shapes) : shapes(shapes.begin(), shapes.end()) {}
向量构造函数会做类似于
的事情
template <typename T>
template <typename It> // SFINAE to avoid to conflict with vector(std::size_t, T) when T=size_t
std::vector<T>::vector<T>(It begin, It end) :
m_size(std::distance(begin, end)),
m_capacity(m_size),
m_data(allocate<T>(m_size))
{
std::size_t i = 0;
for (auto it = begin; it != end; ++it, ++i) {
new (&data[i]) T(*it); // placement new, calling constructor deferencing iterator
}
}
所以在你的情况下
std::initializer_list<Shape *>::iterator it /* = .. */;
Shape* shape = *it;
new (&data[i]) std::unique_ptr<Shape>(shape);
我创建了这个 class,它代表一组形状:
class CompoundShape : public Shape {
private:
std::vector<std::unique_ptr<Shape>> shapes;
public:
CompoundShape(std::initializer_list<Shape *> shapes) : shapes(shapes) {}
void draw() {
for_each(shapes.begin(), shapes.end(), [](auto &shape) { shape->draw(); });
}
};
classShape
还有另一个childclass,SimpleShape
。理想情况下,我想像这样初始化一个 CompoundShape
,而不必担心之后释放指向形状的指针:
CompoundShape shape = {
new SimpleShape(...),
new SimpleShape(...),
new CompoundShape{...},
...
}
我认为唯一的问题是在 CompoundShape
构造函数中,我尝试在其中执行 shapes(shapes)
这当然行不通,因为 std::vector<std::unique_ptr<Shape>>
不能用 std::initializer_list<Shape *> shapes
.
实现此转换的最佳方式是什么?
遗憾的是我们无法使用 std::initializer_list<std::unique_ptr<Shape>>
。
您仍然可以使用带有 2 个迭代器的 vector 构造函数来进行(不是那么明确的)转换:
CompoundShape(std::initializer_list<Shape *> shapes) : shapes(shapes.begin(), shapes.end()) {}
向量构造函数会做类似于
的事情template <typename T>
template <typename It> // SFINAE to avoid to conflict with vector(std::size_t, T) when T=size_t
std::vector<T>::vector<T>(It begin, It end) :
m_size(std::distance(begin, end)),
m_capacity(m_size),
m_data(allocate<T>(m_size))
{
std::size_t i = 0;
for (auto it = begin; it != end; ++it, ++i) {
new (&data[i]) T(*it); // placement new, calling constructor deferencing iterator
}
}
所以在你的情况下
std::initializer_list<Shape *>::iterator it /* = .. */;
Shape* shape = *it;
new (&data[i]) std::unique_ptr<Shape>(shape);