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

Finding first non-empty subtype in template arguments

我正在尝试编写一个 C++ 元函数,它 returns 对我来说是提供的模板参数的第一个非空子类型。

例如:

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

但是,我并不完全熟悉为类型别名实现模板递归。

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

谢谢!

我提议如下

// 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 类型的专业化,最后我们在其他情况下选择了主要版本,因此类型列表为空。

还记得在 static_assert() 测试

中的 std::is_same 之后添加 {}::value
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");