Шаблон Variadic, распаковывающий аргументы в typedef

Учитывая следующий C ++ typedef выражение

template <bool> struct BoolType : std::true_type {};

template <> struct BoolType< false > : std::false_type {};

typedef BoolType< ArgResolver< Arg1 >::IsResolvable::value && ArgResolver< Arg2 >::IsResolvable::value > IsSignatureRecognized;

Я спрашивал себя, можно ли это сделать с помощью шаблона с переменным числом аргументов. Код прибывает из подкожный Контейнер IoC. Как я могу распаковать их, сохраняя при этом && проверить между каждым из них?

3

Решение

Просто напишите and_ метафункция как это:

    template <class ... Bools>
struct and_;

template <class Bool, class ... Bools>
struct and_<Bool, Bools...> : std::conditional<
Bool::value, and_<Bools...>, std::false_type>::type{};

template <>
struct and_<> : std::true_type{};

Я не проверял это, поэтому может быть несколько опечаток, но я надеюсь, что вы поняли идею.

Тогда вы используете это так:

    typedef and_<typename ArgResolver<Args>::IsResolvable...> IsSignatureRecognized;

Как это работает, довольно просто, у нас есть общий класс template <class...> and_ который принимает любое количество типов. Первая специализация проверяет первый аргумент в пакете, если он ложный, нет необходимости продолжать, так как весь and_ будет ложным Если это правда, тогда мы продолжаем проверять остальные параметры. Если больше не осталось параметров, специализация без параметров просто возвращает true.

Вот пример:

and_<t, t, f, t>::value
gives conditional<t::value, and_<t, f, t>, f>::type

Потому что условие верно, type оценивает второй параметр and_<t, f, t>, Аналогично для следующего параметра мы получаем:

and_<f, t>::value
gives conditional<f::value, and_<t>, f>::type

Теперь условие ложно, так type оценивает третий параметр f и мы закончили создание шаблонов и ::value дает нам false,

Если все параметры верны, вы в конечном итоге достигнете and_<> который мы специализируемся std::true_type чтобы ::value дает нам true,

Я надеюсь, что это поможет прояснить, как работает этот код.

3

Другие решения

В C ++ 1z вы можете сделать

using IsSignatureRecognized = BoolType<(ArgResolver<Args>::IsResolvable::value && ...)>;

перед тем, как сделатьand‘ самостоятельно.

4