Std :: conditional time compilation

Compilation:

template < class T, class Y, class ...Args >
struct isSame
{
    static constexpr bool value = std::conditional<
                                      sizeof...( Args ),
                                      typename std::conditional<
                                          std::is_same< T, Y >::value,
                                          isSame< Y, Args... >, // Error!
                                          std::false_type >::type,
                                      std::is_same< T, Y > >::type::value;
};

int main()
{
    qDebug() << isSame< double, int >::value;
    return EXIT_SUCCESS;
}

Gives me this compiler error:

error: wrong number of template arguments (1, should be 2 or more)

The problem is that it isSame< double, int >has an empty package of parameters Args, so it isSame< Y, Args... >effectively becomes isSame< Y >that does not match the signature.

But my question is: why is this thread generally evaluated? sizeof...( Args ) falsetherefore internal std:conditionalshould not be evaluated. This is not a piece of code at runtime; the compiler knows that it sizeof..( Args )will never be truewith the given types of templates.

If you're interested, this should be a variation version std::is_same, not that it works ...

+4
source share
4 answers

, .
, :

#include <type_traits>

template <typename ... Ts> struct are_same;

template <> struct are_same<> : std::true_type {};
template <typename T> struct are_same<T> : std::true_type {};

template <typename T1, typename T2, typename... Ts>
struct are_same<T1, T2, Ts...> :
    std::conditional<
        std::is_same<T1, T2>::value,
        are_same<T2, Ts...>,
        std::false_type
    >::type
{};

static_assert(are_same<char, char, char>::value, "all type should be identical");
static_assert(!are_same<char, char, int>::value, "all type should not be identical");
+3

: ?

, . std::conditional.
, , , .

, . .

+4

std::conditional

, std::conditional, , std::conditional, .. it isSame.

, std::conditional ( ), , , , , , , , .

:


, isSame, sizeof... (Args) == 0, isSame_if_not_empty<Args..>::type, isSame<Args...>, Args , - , .


, isSame Variadic, true, . isSame , , " " .

+3

, . , ::type 2 (bool , ).

, , , , . .

template<template<class...>class Target>struct defer{
  template<class...Ts>using execute=Target<Ts...>;
};
template<class T>struct sink{
  template<class...>using execute=T;
};
template< class Prog, class... Ts > using run=Prog::template execute<Ts...>;

using choice = typename std::conditional< test, defer<Foo>, sink< std::false_type >  >::type;
using result = run< choice, int, double >;

, a defer d Foo, sink d false_type. , Foo<int, double>, false_type.

sink execute , defer template.

, Foo<int, double> , test , choice sink<false_type>!

template<bool b, class A, class B, class...Ts>
using pick = run< typename std::conditional< b, A, B >::type, Ts... >;

using result=pick<test, defer<Foo>, sink<std::false_type>, int, double >;

, choice/result .

, if:

static constexpr bool value =
typename std::conditional< sizeof...( Args ),
  pick< std::is_same< T, Y >::value,
    defer<isSame>,
    sink<std::false_type>,
    Y, Args...
  >,
  std::is_same< T, Y >
>::type::value;

, , .

+3

Source: https://habr.com/ru/post/1543673/


All Articles