假设我们有
class Derived : public Base1, public Base2, ..., public Base<Ts...>> {};
如何编写一个从
std::tuple<Ts...>
获取类型 Derived
的类?也许 Base
也需要作为模板参数传递,以指定要搜索哪个基类。
在这里提供我的具体例子将会让人难以阅读。假设我需要
Ts...
来计算其中有多少满足某个谓词。这个数字是我为每个派生类需要的 constexpr int,但我需要首先获得 Ts...
。
在标准 C++ 中,这是不可能的。
但是,tr2确实有一个类型特征正是这种情况(我只是将它包装在
mp_list
中以方便拼写,因为否则它是一些__reflection_typelist
的东西):
template <class T>
using direct_bases = mp_rename<
typename std::tr2::direct_bases<T>::type,
mp_list>;
你可以这样使用:
template <int I> struct B { };
struct D : B<0>, B<1> { };
static_assert(std::same_as<direct_bases<D>, mp_list<B<0>, B<1>>>);
这只适用于 gcc。如果这不可接受,那么你就必须等待 Reflection。
由于您公开且明确地继承了
Base<Ts...>
,因此您可以使用模板参数推导来获取Ts...
:https://godbolt.org/z/oWfe3z16j
#include <type_traits>
#include <tuple>
namespace detail {
template<template<typename...> class Base, typename... Args> std::type_identity<std::tuple<Args...>> extract_base_args_impl(Base<Args...>*);
}
template<template<typename...> class Base, class Derived>
using extract_base_args_t = decltype(detail::extract_base_args_impl<Base>(static_cast<std::remove_cv_t<Derived>*>(nullptr)))::type;
template<template<typename...> class Base, class Derived>
struct extract_base_args {};
template<template<typename...> class Base, class Derived>
requires(requires { typename extract_base_args_t<Base, Derived>; })
struct extract_base_args<Base, Derived> {
using type = extract_base_args_t<Base, Derived>;
};
你可以在哪里制作
Base
任何你喜欢的模板类。