Re: std::conjunction and SFINAE

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, 29 May 2019 at 19:30, Johan Alfredsson <sduvan.gcc@xxxxxxxxx> wrote:
>
> OK, thanks.  So I guess the eagerness of the template machinery is not
> something you can work around.  Perhaps the only way around this is to
> avoid std::conjunction and explicitly encode a staged evaluation, for
> instance:
>
> template <typename T> constexpr bool is_barable_v =
> std::decay_t<T>::barable::value;
> template <typename T, typename = void>
> struct is_fooable : std::false_type {};
>
> template <typename T>
> struct is_fooable<T, std::void_t<typename std::decay_t<T>::baz>> :
> std::bool_constant<!is_barable_v<T>> {};
>
> struct Foo {
>   using barable = std::false_type;
>   using baz = bool;
> };

That's certainly not the only way, and I disagree that you should
avoid std::conjunction. You should avoid your is_barable_v variable
template, because it evaluates too eagerly.

This works fine:

template <typename T>
using is_fooable_2 = std::enable_if_t<std::conjunction_v<has_baz<T>,
std::negation<typename std::decay_t<T>::barable>>>;

Or:

template <typename T> using is_barable = typename std::decay_t<T>::barable;
template <typename T>
using is_fooable_2 = std::enable_if_t<std::conjunction_v<has_baz<T>,
std::negation<is_barable<T>>>>;



[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux