Я видел, например. соответствующий вопрос на same issue, но у меня другая проблема, которая, я думаю, не может быть решена каким-либо другим способом.Шаблоны шаблонов Variadic variadic, снова
Вот функция any
, которая вычисляет ли унарный предикатF
верно для любого из элементов в представлении аргументов шаблона пакета (список типов) P
:
template <template <typename...> class F, typename P>
struct any;
template <
template <typename...> class F,
template <typename...> class C, typename E, typename... En
>
struct any <F, C <E, En...> > :
public _if <F <E>{}, _true, any <F, C <En...> > > { };
template <template <typename...> class F, template <typename...> class C>
struct any <F, C <> > : public _false { };
где мой _true/_false
эквивалентны std::integral_constant <bool, true/false>
, и _if <C, T, E>
эквивалентно typename std::conditional <C, T, E>::type
(подробности не касаются вопроса, см. ниже).
Например, можно написать
template <typename...> struct pack { };
template <typename T> using is_int = eq <int, T>;
any <is_int, pack <int, void, float, double> >(); // evaluates to true
any <is_int, pack <char, void, float, double> >(); // evaluates to false
, где eq
эквивалентно std::is_same
.
Продолжением бинарных предикатов идет следующим образом:
template <template <typename...> class F, typename P, typename Q>
struct any2;
template <
template <typename...> class F,
template <typename...> class C, typename E, typename... En,
template <typename...> class D, typename H, typename... Hn
>
struct any2 <F, C <E, En...>, D <H, Hn...> > :
public _if <F <E, H>{}, _true, any2 <F, C <En...>, D <Hn...> > > { };
template <
template <typename...> class F,
template <typename...> class C, typename Q
>
struct any2 <F, C <>, Q> : public _false { };
, где мы можем теперь написать
typedef pack <int, void, float, double> A;
typedef pack <void, float, double, int> B;
typedef pack <void, float, double, double> C;
any2 <eq, A, B>(); // false
any2 <eq, A, C>(); // true
Здесь возникает вопрос. Можем ли мы расширить подход к n
-предикаты префикса, действующие на n
ввода "пакеты"?
Данная проблема не совпадает с the previous one, поскольку при оценке F <...>
необходим один элемент каждого входного пакета.
Вот вымышленный попытка:
template <template <typename...> class F, typename... P>
struct any_n;
template <
template <typename...> class F,
template <typename...> class... C, typename... E, typename... En
>
struct any_n <F, C <E, En...>...> :
public _if <F <E...>{}, _true, any_n <F, C <En...>...> > { };
template <
template <typename...> class F,
template <typename...> class C, typename... P
>
struct any_n <F, C <>, P...> : public _false { };
, который, конечно, не компилировать. Итак, можно написать такие вещи, как C <E, En...>...
? Какими будут типы C, E, En
?
Я подозреваю, что ответ отрицательный.
Такой синтаксис был бы чрезвычайно удобным, например, в макросах схемы. Я написал реализацию этого синтаксиса на C++ в прошлом, поддерживая до двух уровней, используя символ dots
или etc
для ...
. Но было бы совершенно иначе иметь поддержку от компилятора (особенно если вам нужно скомпилировать вещь в тот же день).
Tricky! Есть ли у вас пример SSCCE/live? – dyp
@ DyP уверен, встал на [ideone] (http://ideone.com/dFoSmD) – brunocodutra
@brunocodutra Просто просмотрев, я увидел этот ответ, и я не помню, чтобы его видели в это время! Я предпочитаю использовать boost. Мой вопрос был скорее, если это поддерживается языком, и это ясно, и это нужно самому программировать. – iavr