在模板参数中查找第一个非空子类型

时间:2019-03-26 16:39:19

标签: c++ templates recursion variadic-templates template-meta-programming

我正在尝试编写一个C ++元函数,该函数向我返回提供的模板参数的第一个非空子类型。

例如:

struct I { using subtype = int; };
struct D { using subtype = double; };
struct E { using subtype = empty ; };

我正在努力实现:

static_assert(std::is_same<int, first_non_empty_subtype<E,E,I>>::value, "the first non-empty subtype should be 'int'");
static_assert(std::is_same<double, first_non_empty_subtype<E,D,I>>::value, "the first non-empty subtype should be 'double'");
static_assert(std::is_same<empty, first_non_empty_subtype<E,E,E>>::value, "since all subtypes are empty, the result is empty");

我最初的想法是在模板递归中使用std::conditional_t

template <typename T, typename ...Ts>
using first_non_empty_subtype = std::conditional_t<
    !std::is_empty<typename T::subtype>::value, 
    typename T::subtype, 
    first_non_empty_subtype<Ts...>>::type

但是,我对实现类型别名的模板递归并不十分熟悉。

有人可以帮我指出解决这个问题的正确方向吗?

谢谢!

1 个答案:

答案 0 :(得分:1)

我提出如下建议

// ground case: no more types, so empty
template <typename ...>
struct fnes_helper
 { using type = empty; };

// the first type is T and isn't empy; so T
template <typename T, typename ... Ts>
struct fnes_helper<T, Ts...>
 { using type = T; };

// the first type is empty; so recursion
template <typename ... Ts>
struct fnes_helper<empty, Ts...> : public fnes_helper<Ts...>
 { };

template <typename ... Ts>
using first_non_empty_subtype 
   = typename fnes_helper<typename Ts::subtype...>::type;

观察到fnes_helper更专业的版本是empty类型在第一位的版本,在这种情况下使用的版本也是如此。 紧跟另一种专业,即第一类的通用T类型,最后在其他情况下我们选择了主版本,因此类型列表为空。

还记得在{}测试的::value之后添加std::is_samestatic_assert()

static_assert(std::is_same<int, first_non_empty_subtype<E,E,I>>{},
              "the first non-empty subtype should be 'int'");
static_assert(std::is_same<double, first_non_empty_subtype<E,D,I>>{},
              "the first non-empty subtype should be 'double'");
static_assert(std::is_same<empty, first_non_empty_subtype<E,E,E>>{},
              "since all subtypes are empty, the result is empty");