
Boost : 
Subject: Re: [boost] "Simple C++11 metaprogramming"
From: Peter Dimov (lists_at_[hidden])
Date: 20150605 09:23:13
Eric Niebler wrote:
> 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.
It does. I now need a SFINAEfriendly defer in addition to eval_or_default.
// 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>
using builtin_common_type =
decltype(declval<bool>()? declval<T1>(): declval<T2>());
template<class T1, class T2>
struct common_type<T1, T2>:
mp_if_c<
std::is_same<T1, std::decay_t<T1>>::value
&& std::is_same<T2, std::decay_t<T2>>::value,
mp_defer<builtin_common_type, T1, T2>,
common_type<std::decay_t<T1>, std::decay_t<T2>>>
{
};
template<class T1, class T2, class... T>
using common_type_impl =
common_type<typename common_type<T1, T2>::type, 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...>
{
};
mp_defer was before just
template<template<class...> class F, class... T> struct mp_defer
{
using type = F<T...>;
};
but now has to be
// mp_defer
struct empty
{
};
template<template<class...> class F, class... T> struct mp_defer_impl
{
using type = F<T...>;
};
template<template<class...> class F, class... T>
using mp_defer =
mp_if<is_evaluable<F, T...>, mp_defer_impl<F, T...>, empty>;
> 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 SFINAEfriendliness 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?
I can use a fold if the fold is SFINAEfriendly, yes. But I'm not yet
convinced that it has to be. This would imply making all algorithms
SFINAEfriendly, or making fold an exception, or adding both
SFINAE/nonSFINAE variants of some. None of those sounds appealing.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk