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

问题描述 投票:0回答:3

假设我有一个

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

c++ boost variant boost-variant
3个回答
0
投票
boost::variant<Point*, Line*, Circle*> 

然后

shape = &p;

然后让你的访问者超载指针。


0
投票

您不能在

variant
中存储引用(请参阅
std::variant
引用
,它明确说明了这一点,但
boost::variant
非常相似),因为引用只是变量的另一个名称。
variant
union
的奇特实现。在这两种情况下,该值都存储在union/
variant
中。将您的对象放在那里可能需要付出副本的代价。

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

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

使用指针,您甚至可能决定使用传统的多态方法而不是使用 
variant

来实现此功能(定义一个抽象类

shape
Point
Line
Circle
继承自并使
s
成为父类型的指针:

shape s = &p;

请注意,
后者比使用

variant

更容易出错。


0
投票
可以

将参考存储在boost::variant中。

对于这样的变体,默认构造函数和复制运算符
可能会成为一个问题。
但更重要的是:您必须关心设备的生命周期 自己存储引用(没有像shared_ptr那样的引用计数)。
如果这对你来说没问题,你可以尝试这样的事情:

using ShapeRef = boost::variant< Circle&, Square& >; void resize_shape( ShapeRef _shape, double _val ) { switch(_shape.which()) { case 0: boost::get<Circle&>(_shape).setradius( _val ); return; case 1: boost::get<Square&>(_shape).setsize( _val ); return; default: throw Oops(); } } Circle c(10); Square s(10); resize_shape( c, 5 ); resize_shape( s, 5 );

	
© www.soinside.com 2019 - 2024. All rights reserved.