【发布时间】:2018-04-18 16:39:36
【问题描述】:
问题。
我是模板元编程的新手,不确定如何实现 在提供时生成类型的元组上的类型过滤转换 带有过滤说明。我相信以下代码 sn-p 演示 我想要的行为。
enum : int {
INCLUDE,
EXCLUDE
};
template <int filter_val, class T>
struct filter {
};
int
main() {
struct A {};
struct B {};
struct C {};
typedef std::tuple<filter<INCLUDE, A>,
filter<EXCLUDE, B>,
filter<INCLUDE, C>> filters;
typedef filter_all<filters>::type filtered;
static_assert(std::is_same<filtered,
std::tuple<A, C>
>::value,
":(");
return 0;
}
我的尝试
据我所知,您不能解压缩超过 1 个独立的可变参数模板,因此我考虑解决问题的方法是在递归模板专业化过程中维护两个元组,其中一个代表我们在递归中的位置,而另一个表示到目前为止包含的 T。
template <template <class ...> class, class ...Unfiltered_Ts>
struct filter_all {
private:
template <class Unfiltered_Ts_Tuple, class Included_Ts_Tuple>
struct filter_all_impl;
// CASE 1: Include T in the result
template <
template <int, class> class, int filter_val, class T, class ...Unfiltered_Ts_impl, // Unfiltered input
template <class ...> class, class ...Included_Ts // Result so far
>
struct filter_all_impl<std::tuple<filter<INCLUDE, T>,
Unfiltered_Ts_impl...>,
std::tuple<Included_Ts...>> {
typedef typename
filter_all_impl<std::tuple<Unfiltered_Ts_impl...>,
std::tuple<Included_Ts..., T> // Append T to result
>::type type;
};
// CASE 2: Don't include T in the result
template <
template <int, class> class, int filter_val, class T, class ...Unfiltered_Ts_impl, // Unfiltered input
template <class ...> class, class ...Included_Ts // Result so far
>
struct filter_all_impl<std::tuple<filter<EXCLUDE, T>,
Unfiltered_Ts_impl...>,
std::tuple<Included_Ts...>
> {
typedef typename
filter_all_impl<std::tuple<Unfiltered_Ts_impl...>,
std::tuple<Included_Ts...> // Don't append T to result
>::type type;
};
// CASE 3: Filtering finished - set the final type as the included T's
template <
template <int, class> class, int filter_val, class T, class ...Unfiltered_Ts_impl,
template <class ...> class, class ...Included_Ts
>
struct filter_all_impl<<>, // empty
std::tuple<Included_Ts...>
> {
// Final step, set type as a tuple of all included Ts
typedef std::tuple<Included_Ts...> type;
};
public:
typedef typename filter_all_impl<
std::tuple<Unfiltered_Ts...>, // Initially contains all unfiltered Ts
std::tuple<> // Initially empty filtered Ts which eventually becomes the return type
>::type type;
};
我希望有一种更简单的方法来进行这种转换,但这是我到目前为止所达到的,但它远未编译,并抱怨模板专业化无效。任何指导表示赞赏。
【问题讨论】:
-
希望我能两次支持这个问题。感谢您的明确解释、测试驱动程序以及您的尝试。
标签: c++ templates metaprogramming