Boost logo

Boost :

Subject: Re: [boost] [variant] Breaking change introduced by variadic support
From: Antony Polukhin (antoshkka_at_[hidden])
Date: 2014-01-18 12:32:35

2014/1/18 Agustín K-ballo Bergé <kaballo86_at_[hidden]>

> The recent changes to introduce variadic support to `variant` introduce
> breaking changes in the documented macros. When variadic support is
> detected, `BOOST_VARIANT_LIMIT_TYPES` is not defined and
> `BOOST_VARIANT_ENUM_[SHIFTED_]PARAMS` uses variadic templates instead of
> enumerating parameters.
> This is a breaking change in the documented interface, and one that
> requires all but the simplest use cases to be rewritten. For instance, this
> breaks _Boost.Spirit_ support of `variant` (
> boost/ticket/9238), requiring two different implementations to be
> provided.
> Is this the preferred path to take? I would suggest instead to keep the
> macros as documented at all times, and let the user handle the variadic
> case manually. This would allow users to support both variadic and
> non-variadic `variant`s up to a certain limit with a single code case
> (without breaking the documented interface), and result in cleaner code for
> those cases that only target compilers with variadic support. There's no
> point in using a macro if it won't work for both cases.

Unfortunately this will make previous code just "look like" it works.
Variadic template version of variant (`variant<T0, TN...>`) is not same as
variant generated by BOOST_VARIANT_LIMIT_TYPES and preprocessor
(`variant<T0, T1, T2, T3, T4, T5, T6, T7, T8>`). Leaving
BOOST_VARIANT_LIMIT_TYPES defined will result in many-many hard detectable
template errors.

Here is an example

template <class T> struct is_variant: boost::false_type {};

template </*`class TX` generated by handwritten preprocessor code and
struct is_variant< variant</*`TX` generated by handwritten preprocessor
: boost::true_type {};

Following code will produce different results, depending on availability of
variadic templates:
is_variant<variant<int, char> >::value
That's because *there is* a difference between variant<T0, TN...> and
variant<T0, T1, T2, T3, T4, T5, T6, T7, T8>

I've put a lot of effort to make transition as smooth as possible:
* users that use BOOST_VARIANT_ENUM_[SHIFTED_]PARAMS shall notice no change:
// BOOST_VARIANT_ENUM_PARAMS(class Something) => class
Something0, class... SomethingN
// BOOST_VARIANT_ENUM_PARAMS(Something) => Something0,
* users are free to define BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES and
do not use variadic templates version at all.
* users that use BOOST_VARIANT_LIMIT_TYPES won't get silent templates
errors and will be able to take care about the issues.

Any ideas about how to make transition smoother are welcomed!

Best regards,
Antony Polukhin

Boost list run by bdawes at, gregod at, cpdaniel at, john at