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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With