Suppose we have
class Derived : public Base1, public Base2, ..., public Base<Ts...>> {};
How to write a class that obtains the type std::tuple<Ts...>
from Derived
? Perhaps Base
needs to be passed as a template argument too, to specify which base class to search for.
Providing my concrete example here will be overwhelming to read. Let's just say I need the Ts...
in order to count how many of them satisfy a certain predicate. This number is the constexpr int I need for each derived class, but I need to obtain the Ts...
first.
Since you publically and unambiguously inherit from a Base<Ts...>
, you can use template argument deduction to get the 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>;
};
Where you can make Base
whatever template class you like.