如何在 boost::variant<T> 中存储引用而不是复制对象?

Posted

技术标签:

【中文标题】如何在 boost::variant<T> 中存储引用而不是复制对象?【英文标题】:How to store a reference in boost::variant<T> instead of copying the object? 【发布时间】:2019-05-27 21:18:12 【问题描述】:

假设我有一个boost::variant 定义为boost::variant&lt;Point, Line, Circle&gt; shape。现在,如果我创建 Point 类的对象,Point p 并将其存储为shape = p,我在这里所做的是制作 p 的副本。我如何实际存储对 p 的引用,这样当我调用 boost::apply_visitior(visitor, shape) 时,访问者不仅会改变存储在变体中的 Point,还会改变 p 本身?

【问题讨论】:

你不能,或者改变你的形状以允许参考。 【参考方案1】:
boost::variant<Point*, Line*, Circle*> 

然后

shape = &p;

然后让您的访问者在指针上过载。

【讨论】:

【参考方案2】:

您不能在variant 中存储引用(参见std::variant reference,它明确说明了这一点,但boost::variant 非常相似),因为引用只是变量的另一个名称。 variantunion 的一个奇特实现。在这两种情况下,值都存储在内部union/variant。将您的对象放入其中可能会以副本为代价。

对于小物件,我不会担心副本。如果您的对象很大并且您需要避免复制,您可能需要考虑使用指针:

boost::variant<Point*, Line*, Circle*> shape;
shape s = &p;

使用指针,您甚至可能决定使用传统的多态方法而不是使用variant 来实现它(定义一个抽象类shapePointLineCircle 继承自@987654336,并使@987654336 @父类型的指针:

shape s = &p;

注意the latter can be more error prone than using variant

【讨论】:

以上是关于如何在 boost::variant<T> 中存储引用而不是复制对象?的主要内容,如果未能解决你的问题,请参考以下文章

boost::variant 如何存储引用?

使用 boost::variant 调用模板类函数

如何返回由 boost::variant 返回类型中包含的类型的子集组成的 boost::variant

指向带有 boost::variant 的成员函数的指针

使用 boost::variant 库制作地图。如何将事物存储和显示为正确的类型?

使用 boost::variant C++ 的隐式运算符重载