我已经看到例如关于同一问题的相关问题,但我有一个不同的问题,我认为无法以任何其他方式解决。
这是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 { };
其中 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 谓词,对n
输入“包”进行操作吗?
这个问题与前一个问题不同,每个输入包的一个元素同时需要用于评估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 宏中。我过去曾编写过此语法的 C++ 模板实现,最多支持两个级别,使用 symboldots
或etc
for ...
。但是获得编译器的支持会完全不同(尤其是如果您需要在同一天编译该东西)。