4

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 Answers1

4

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"));
Community
  • 1
  • 1
Richard Hodges
  • 68,278
  • 7
  • 90
  • 142