Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

boost::variant with immovable types

I have a type T that does not support movement:

struct T {
    T();
    T(T const&) = delete;
    T& operator=(T const&) = delete;
    T(T&&) = delete;
    T& operator=(T&&) = delete;
};

How do I create an object of type boost::variant<T>? The following fails, because the constructor of boost::variant<T> obviously tries to move the argument:

boost::variant<T> x(T());

1 Answers

Unhappily for you, the documentation says that any type in the template argument list of a variant must be a BoundedType, which is defined thus:

BoundedType

The requirements on a bounded type are as follows:

CopyConstructible or MoveConstructible.

Destructor upholds the no-throw exception-safety guarantee.

Complete at the point of variant template instantiation. (See boost::recursive_wrapper for a type wrapper that accepts incomplete types to enable recursive variant types.)

Every type specified as a template argument to variant must at minimum fulfill the above requirements. In addition, certain features of variant are available only if its bounded types meet the requirements of these following additional concepts... (etc.)

So it looks as though you'll need to either store a reference, or more likely a std::unique_ptr<T> in the variant (or some wrapper of T which encapsulates the smart pointer).

something like this:

struct shared_t {

    // insert appropriate constructors here, such as:

    shared_t(std::string arg1) : _ptr(std::make_shared<T>(std::move(arg1))) 
    {}

    operator T&() { return *_ptr; }
    operator const T&() const { return *_ptr; }

    std::shared_ptr<T> _ptr;
};

using my_variant = boost::variant<shared_t, int, double, std::exception_ptr, ...>;

my_variant v(shared_t("foo"));
like image 169
Richard Hodges Avatar answered Oct 24 '25 01:10

Richard Hodges



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!