CRTP + variadic template + extract CRTP subclass parameters
c++, c++11, crtp, templates, variadic-templates
Solution
You could leave the primary template of `CRTPBase` undefined:
template<typename T> class CRTPBase;
And then partially specialize it this way:
template<template<typename, typename...> class TT,
typename SENDER, typename... ARGS>
class CRTPBase<TT<SENDER, ARGS...>>
{
// ...
};
Here is a simple program that shows the type arguments could be retrieved in `CRTPBase`:
#include <tuple>
#include <type_traits>
template<typename T> class CRTPBase;
template<template<typename, typename...> class TT,
typename SENDER, typename... ARGS>
class CRTPBase<TT<SENDER, ARGS...>>
{
using type = std::tuple<SENDER, ARGS...>;
};
template<typename SENDER , typename... ARGS>
class event : public CRTPBase<event<SENDER,ARGS...>>
{
// ...
};
struct X { };
int main()
{
event<X, int, double> e;
// This assertion will not fire!
static_assert(std::is_same<
decltype(e)::type,
std::tuple<X, int, double>
>::value, "!");
}
Here is the corresponding live example.
Problem
Im currently implementing a generic event class. Event handlers have a sender parameter and a variable number of event args. So the declaration of the event class is as bellow: ``` template<typename SENDER , typename... ARGS> class event; ``` To allow certain implementation details, I need a CRTP of the event, like this: ``` template<typename SENDER , typename... ARGS> class event : public CRTPBase<event<SENDER,ARGS...>> { ... }; ``` And the CRTP base needs to know the event parameters. So I have tried with a template template param: ``` template<typename SENDER , template<typename SENDER , typename... ARGS> class EVENT, typename ARGS> class CRTPBase { ... }; ``` But this doesn't work (Im using GCC 4.8.1). So: What is the best way to extract the variadic and non-variadic template parameters of the argument of a CRTP? EDIT: Another way is to provide event parameters directly through the CRTP template (`template<typename EVENT , typename EVENT_SENDER , typename... EVENT_ARGS> class CRTPBase;` ), but I think there is a way to do this directly, without writting the params in a explicit way.