Учитывая следующий 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. Как я могу распаковать их, сохраняя при этом &&
проверить между каждым из них?
Просто напишите 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
,
Я надеюсь, что это поможет прояснить, как работает этот код.
В C ++ 1z вы можете сделать
using IsSignatureRecognized = BoolType<(ArgResolver<Args>::IsResolvable::value && ...)>;
перед тем, как сделатьand
‘ самостоятельно.