Subject: Re: [boost] [variant] Breaking change introduced by variadic support
From: Agustín K-ballo Bergé (kaballo86_at_[hidden])
Date: 2014-01-18 13:00:38
On 18/01/2014 02:32 p.m., Antony Polukhin wrote:
> 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` (https://svn.boost.org/trac/
>> boost/ticket/9238), requiring two different implementations to be
>> 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.
Nod, this is unfortunate but at least the current approach results in
hard to diagnose *compilation* errors, which is better IMO.
> 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,
This is not the case, see the compilation failure in Spirit. The enum
macros are documented to define param##N arguments.
Additionally, dealing with all template arguments at the same time gives
better compile-time performance than recursive approaches. This is not
prevented by variadic templates, but having them separated in head and
tail do make it slightly more complicated. I would still suggest that
the variadic case we handled manually by the user, while the macros
would be there only to support the simplest existing use cases.
> * users are free to define BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES and
> do not use variadic templates version at all.
The end user may be free to define it, libraries cannot.
> * 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!
I will continue thinking about this. I find unfortunate that users are
forced to provide different codes for variadic and non-variadic cases.
Worse, the compilation errors do not point to `variant` at all, and one
would not usually suspect that a macro named `ENUM` does not enumerate
-- Agustín K-ballo Bergé.- http://talesofcpp.fusionfenix.com
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk