【发布时间】:2013-09-17 14:02:32
【问题描述】:
我见过例如same issue 上的一个相关问题,但我有一个不同的问题,我认为无法以任何其他方式解决。
这是函数 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-ary 谓词,对n 输入“packs”进行操作?
此问题与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 表示 ...。但是得到编译器的支持就完全不一样了(尤其是如果你需要在同一天编译这个东西)。
【问题讨论】:
标签: c++ c++11 variadic-templates