Boost logo

Boost :

Subject: Re: [boost] "Simple C++11 metaprogramming"
From: Eric Niebler (eniebler_at_[hidden])
Date: 2015-06-05 03:49:18


On 6/4/2015 4:30 PM, Peter Dimov wrote:
> Eric Niebler wrote:
>
>> I made Meta SFINAE-friendly on a lark and found it useful in practice.
>> (See this thread[*] where Louis and I compared common_type
>> implementations with Meta and Hana.)
> ...
>> [*] http://lists.boost.org/Archives/boost/2015/03/220446.php
>
> Having a SFINAE-friendly fold helps, but here's my implementation of
> this challenge.
>
> // common_type
>
> template<class...> struct common_type
> {
> using type_not_present = void***[];
> };
>
> template<class T> struct common_type<T>: std::decay<T>
> {
> };
>
> template<class T1, class T2, class... T>
> using common_type_impl =
> common_type<decltype(declval<bool>()? declval<T1>(): declval<T2>()),
> T...>;
>
> template<class T1, class T2, class...T>
> struct common_type<T1, T2, T...>:
> eval_or_default<common_type<>, common_type_impl, T1, T2, T...>
> {
> };
>
> #include <iostream>
> #include <typeinfo>
>
> int main()
> {
> std::cout << typeid( common_type<char volatile[], void*, int const[],
> void*>::type ).name() << std::endl;
> std::cout << typeid( common_type<char, float, int*,
> double>::type_not_present ).name() << std::endl;
> }
>
> where eval_or_default<Def, F, T...> checks is_evaluable<F, T...> (from
> Bruno Dutra's earlier message) and returns F<T...> if evaluable, Def if
> not.
>
> Getting it right was a bit tricky, but I find the final result quite
> readable. (This implements the specification in the latest C++17 draft.)

I'm not so sure. If a user defines a specialization for
common_type<MyInt, int>, it won't get used when computing
common_type<MyInt, int, int>. I think that would complicate your
implementation somewhat. I like the mutual recursion between common_type
and common_type_impl, but really you've just implemented fold, and it
would be better to have fold as a separate reusable algorithm. I see
that you've isolated the SFINAE-friendliness in your library to the
eval_or_default utility. It's an interesting choice, but I think it's
why you can't use a fold here, am I right?

-- 
Eric Niebler
Boost.org
http://www.boost.org

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk