从基类获取类型

问题描述 投票:0回答:2

假设我们有

class Derived : public Base1, public Base2, ..., public Base<Ts...>> {};

如何编写一个从

std::tuple<Ts...>
获取类型
Derived
的类?也许
Base
也需要作为模板参数传递,以指定要搜索哪个基类。

在这里提供我的具体例子将会让人难以阅读。假设我需要

Ts...
来计算其中有多少满足某个谓词。这个数字是我为每个派生类需要的 constexpr int,但我需要首先获得
Ts...

c++ templates c++20 template-meta-programming
2个回答
0
投票

在标准 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。


0
投票

由于您公开且明确地继承了

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
任何你喜欢的模板类。

© www.soinside.com 2019 - 2024. All rights reserved.