在模板参数中查找第一个非空子类型
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");
我正在尝试编写一个 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");