c++ variant class member stored by reference

懵懂的女人 提交于 2019-12-02 04:11:13

It doesn't work because this statement A a1(simple); creates a temporary variant object!

You then proceed to bind said temporary to your const reference. But the temporary goes out of scope immediately after the construction of a1 is over, leaving you with a dangling reference. Creating a copy works, obviously, since it always involves working with a valid copy.

A possible solution (if the performance of always copying worries you) is to accept a variant object by-value, and then move it into your local copy, like so:

explicit A(VectorOrSimple<int> arg) : member(std::move(arg)) {
    print();
}

This will allow your constructor to be called with either lvalues or rvalues. For lvalues your member will be initialized by moving a copy of the source variant, and for rvalues the contents of the source will just be moved (at most) twice.

Variants are objects. They contain one of a set of types, but they are not one of those types.

A reference to a variant is a reference to the variant object, not a reference to one of the contained types.

A variant of reference wrappers may be what you want:

template<class...Ts>
using variant_ref=std::variant<std::reference_wrapper<Ts>...>;

template<typename T>
using VectorOrSimple = std::variant<T, std::vector<T>>;
template<typename T>
using VectorOrSimpleRef = variant_ref<T, std::vector<T>>;
template<typename T>
using VectorOrSimpleConstRef = variant_ref<const T, const std::vector<T>>;

Now store VectorOfSimpleConstRef<int>. (Not const&). And take one in the constructor as well.

Also modify Print to take by const& to avoid needlessly copying that std::vector when printing.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!