我正在尝试编写一个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
但是,我对实现类型别名的模板递归并不十分熟悉。
有人可以帮我指出解决这个问题的正确方向吗?
谢谢!
答案 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_same
或static_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");