c++boostboost-variantboost-variant2

Why are there two variant class implementations in Boost?


Boost seems to have two implementations of a variant class template:

It is rare (though not unheard of) for Boost to include two takes on the same concept. Why has this happened for variants? How do these variants differ?


Solution

  • The first kind of variant class template, boost::variant, predates C++17's std::variant. See this question for its comparison to std::variant. Mainly, the difference regards what to do when an exception is thrown on construction of a value within the variant.

    The std::variant choice is to allow a valueless state; the boost::variant choice is to construct the new object on the heap, not in-place, and store a pointer to that location.

    boost::variant2 is a later addition, which, on the one hand, wishes to adhere to the C++17 API, but on the other hand is an expression of dissatisfaction with its choice on this matter.

    boost::variant2 chooses a third option, different than both previous implementations: double-buffering. It takes up twice the size of the problematic type; constructs a new value in the unused half, and once the construction succeeds - destroys the old value in the other half. If all types are nothrow-move-constructible, this is not necessary and boost::variant2 will not actually have the double buffer.

    This choice means that boost::variant2 can never be valueless; and indeed, its documentation title emphasizes this fact.