たとえば、同じ問題に関する関連する質問を見たことがありますが、別の問題があり、他の方法では解決できないと思います。
テンプレート引数パック表現 (型のリスト) のいずれかの要素に対して単項述語any
が true であるかどうかを計算する関数を次に示します。 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 { };
ここで、 my_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
-ary predicateへのアプローチを拡張できますか?n
この問題は、各入力パックの 1 つの要素が の評価に同時に必要であるという点で、前の問題とは異なり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
ますか?
答えはノーだと思います。
このような構文は、Scheme マクロなどで非常に便利です。dots
過去に、シンボルまたはetc
forを使用して、最大 2 つのレベルをサポートするこの構文の C++ テンプレート実装を作成しました...
。しかし、コンパイラからのサポートがある場合はまったく異なります (特に、同じ日にコンパイルする必要がある場合)。