c++ - 如何编写将变体类类型的对象添加到向量的模板函数?
问题描述
我还有一个问题,我不知道如何解决。也许有人可以帮助我。
我想做的事:我有一个向量,它应该包含各种类类型的元素。在我的示例代码中,我有两个类(Line、circle),它们都派生自一个虚拟类段。我的代码将链接几个圆形或线条元素并将它们放入向量中。每个元素可能彼此不同(不同的半径、不同的起点和终点等),并且元素的顺序因执行而异。例如,对于第一次执行,我有一个半径为 2 的圆,然后是另一个半径为 1 的圆,然后是一条长度为 4 的线,对于第二次执行,我有一条长度为 1 的线,然后是另一条长度为 5 的线一个不同的方向,然后是一个半径为 0.5 的圆。
我已经学会了如何组合向量,使其可以包含不同的类型,但到目前为止,每个元素的序列和定义都是硬编码的。现在我想让它变得灵活(最后序列和定义应该是文件驱动的)。为此,我尝试实现一个模板函数,该函数将输入的任何元素添加到向量中。当前定义也将向量作为输入,但我可能最终将此函数定义为向量的方法。
不幸的是,我无法弄清楚如何做到这一点。我知道我无法复制 aunique_ptr
所以我尝试了该std::move()
方法但不起作用。我在第 671 行收到 xmemory 模块的 C2664 错误消息,说我无法将 T2 中的参数 1 转换为 std::nullptr_t。
有人可以在这里帮助我吗?那会太棒了!
这是我的示例代码,它实现了我的代码的基本思想:
#include <iostream>
#include <vector>
#include <variant>
struct point
{
double x;
double y;
};
class segment
{
public:
segment()
{
P1.x = 0;
P1.y = 0;
P2.x = 0;
P2.y = 0;
};
virtual ~segment() {};
virtual double get_radius() { return 0; };
virtual double get_length() { return 0; };
virtual double get_angle() { return 0; };
int segment_id = 0;
protected:
point P1;
point P2;
};
class Line : public segment
{
public:
Line() {};
Line(const point pt1, const point pt2)
{
P1.x = pt1.x;
P1.y = pt1.y;
P2.x = pt2.x;
P2.y = pt2.y;
segment_id = 1;
};
~Line() {};
double get_length() { return calc_length(); };
double get_angle() { return calc_angle(); };
private:
double calc_length()
{
// calculate length (here: dummy value)
return 1;
}
double calc_angle()
{
// calculate angle (here: dummy value)
return 0.5;
}
double length = 0;
double angle = 0;
}
;
class circle : public segment
{
public:
circle()
{
center.x = 0;
center.y = 0;
};
circle(const double r, const point c)
{
radius = r;
center.x = c.x;
center.y = c.y;
segment_id = 2;
};
~circle() {};
double get_radius() { return radius; };
point get_center() { return center; };
double get_length() { return 3.14 * radius; }; //returns circumference
private:
double radius = 0;
point center;
};
//-------------------------------------------------------
//T1: class type "segment", T2: class object Line or circle
template<typename T1, typename T2>
inline void add_segment(T1 v, T2 line_or_circle)
{
v.emplace_back(line_or_circle);
}
//-------------------------------------------------------
int main()
{
int nbr = 5;
point start;
start.x = 1;
start.y = 2;
point end;
end.x = 3;
end.y = 4;
point c;
c.x = 0;
c.y = 0;
double r = 9;
auto anotherCircle = std::make_unique<circle>(r, c);
auto anotherLine = std::make_unique<Line>(start, end);
circle myCircle(r, c);
//VERSION 1: Does now compile.
std::vector<std::unique_ptr<segment>> v1;
v1.emplace_back(std::move(anotherCircle));
v1.emplace_back(std::move(anotherLine));
std::cout << v1[0]->get_radius() << std::endl;
std::cout << v1[1]->segment_id << std::endl;
//VERSION 2: Compiles
std::vector<std::unique_ptr<segment>> v2;
v2.emplace_back(std::make_unique<circle>(r, c));
v2.emplace_back(std::make_unique<Line>(start, end));
//=================================================================
//now I want to implement this as a function call
//=================================================================
std::vector<std::unique_ptr<segment>> v3;
//VERSION 5:
auto myLine2 = std::make_unique<Line>(start, end);
add_segment(v3, std::move(myLine2)); //shall add object of class Line or circle (derived from virtual segment class, see above) to vector v3. In this example a Line but might be a circle
}
解决方案
您的函数add_segment
按值获取向量。这无法编译,因为向量是不可复制的,因为唯一指针是不可复制的。即使您使用了可复制的指针类型,这也是一种毫无意义的方法,因为副本在函数结束时被销毁。
您还需要将line_or_circle
参数移动到add_segment
.
template<typename T1, typename T2>
inline void add_segment(T1 & v, T2 line_or_circle)
{
v.emplace_back(std::move(line_or_circle));
}
推荐阅读
- javascript - 如何记录此 GET 请求 json 的部分内容
- php - 如何使用 MYSQL ZEND1.12 存储和显示表单中的图像
- javascript - 如何在javascript中访问li标签?
- python - JSON数组到熊猫中的一种热编码
- kubernetes - pod 可以在 k8s 杀死之前引发 SYSTEM OOM 吗?
- python - 芹菜在python中有什么用?
- html - 如何在包装器中使用 flexbox?
- sql - 为什么我的参数化查询不能正确使用索引?
- android - EditText上的Android自动完成背景黄色
- typescript - 打字稿根据参数返回不同的接口