将指向给定子类的指针从一个向量复制到另一个向量

Copying pointers to a given subclass from one vector to the other one

本文关键字:向量 一个 复制 另一个 子类 指针      更新时间:2023-10-16

我有一个问题(你可以猜到,因为我写了这篇文章(。我确实有 1 个基类和 2 个子类(图形、三角形、矩形(。

数字

class Figure
{
protected:
std::string color;
public:
Figure(std::string color);
virtual ~Figure();
};
Figure::Figure(std::string color) : color(color) {}

三角形

class Triangle : public Figure
{
private:
unsigned int base;
unsigned int height;
public:
Triangle(std::string color, unsigned int base, unsigned int height);
};
Triangle::Triangle(std::string color, unsigned int base, 
unsigned int height) : Figure(color), base(base), height(height) {}

矩形

class Rectangle : public Figure
{
private:
unsigned int side1;
unsigned int side2;
public:
Rectangle(std::string color, unsigned int side1, unsigned int side2);
};
Rectangle::Rectangle(std::string color, unsigned int side1, 
unsigned int side2) : Figure(color), side1(side1), side2(side2) {}

在主要版本中,我创建了一个包含一些共享指针的向量。例如(缩短版本(:

std::vector<std::shared_ptr<Figure>> figures;
figures.push_back(std::make_shared<Triangle>("Red",4,10));
figures.push_back(std::make_shared<Triangle>("Blue", 2, 6));
figures.push_back(std::make_shared<Rectangle>("Orange", 4, 8));

现在,taks 是只选择指向三角形子类的指针(来自图形向量(,并将它们放入另一个新向量(三角形向量(中。

我尝试了一些解决方案,但没有一个奏效。

std::vector<std::shared_ptr<Triangle>> triangles;
std::copy_if(figures.begin(), figures.end(), triangles.begin(), [](auto fig) {
std::shared_ptr<Triangle> el = std::dynamic_pointer_cast<Triangle>(fig);
return !(el == nullptr);
});

第二

std::vector<std::shared_ptr<Triangle>> triangles;
std::transform(figures.begin(), figures.end(), triangles.begin(), [](auto fig) {
std::shared_ptr<Triangle> el = std::dynamic_pointer_cast<Triangle>(fig);
if(el != nullptr) return el;
});

可能尝试解决它的第一个方法更接近正确的方法,但它不起作用。

感谢您的帮助

目前没有std::transform_if,因此您可以通过 2 次进行:

std::vector<std::shared_ptr<Triangle>> triangles;
std::transform(figures.begin(),
figures.end(),
std::back_inserter(triangles),
[](auto fig) { return std::dynamic_pointer_cast<Triangle>(fig); });
triangles.erase(std::remove(triangles.begin(), triangles.end(), nullptr), triangles.end());

你可以写一个transform_if,或者一个更具体的copy_of_type

template<class InputIt, class OutputIt, class Predicate, class UnaryOperation>
OutputIt transform_if(InputIt first1, InputIt last1, OutputIt d_first, Predicate pred, UnaryOperation unary_op)
{
while (first1 != last1) {
auto && val = unary_op(*first1++);
if (pred(val)) {
*d_first++ = val;
}
}
return d_first;
}
template<class InputIt, class OutputIt, class Cast>
OutputIt copy_of_type(InputIt first1, InputIt last1, OutputIt d_first, Cast cast)
{
while (first1 != last1) {
auto && val = cast(*first1++);
if (val) {
*d_first++ = val;
}
}
return d_first;
}

将使用哪个

transform_if(figures.begin(),
figures.end(),
std::back_inserter(triangles),
[](auto fig) { return std::dynamic_pointer_cast<Triangle>(fig); },
[](auto fig) { return std::dynamic_pointer_cast<Triangle>(fig); });
copy_of_type(figures.begin(),
figures.end(),
std::back_inserter(triangles),
[](auto fig) { return std::dynamic_pointer_cast<Triangle>(fig); });