2013-07-07 3 views
3

Im в настоящее время реализует общий класс событий. Обработчики событий имеют параметр отправителя и переменное количество аргументов событий. Таким образом, декларация класса событий как ниже:CRTP + variadic template + extract Параметры подкласса CRTP

template<typename SENDER , typename... ARGS> 
class event; 

Чтобы разрешить некоторые детали реализации, мне нужно CRTP события, как это:

template<typename SENDER , typename... ARGS> 
class event : public CRTPBase<event<SENDER,ARGS...>> { ... }; 

И основание CRTP нужно знать параметры события. Поэтому я попытался с шаблоном шаблона param:

template<typename SENDER , template<typename SENDER , typename... ARGS> class EVENT, typename ARGS> 
class CRTPBase { ... }; 

Но это не сработает (я использую GCC 4.8.1).

So: Каков наилучший способ извлечения вариационных и невариантных параметров шаблона аргумента CRTP?

EDIT: Другой способ заключается в обеспечении параметров событий непосредственно с помощью шаблона CRTP (template<typename EVENT , typename EVENT_SENDER , typename... EVENT_ARGS> class CRTPBase;), но я думаю, что есть способ сделать это напрямую, без сочинительства в Params в явном виде.

ответ

6

Вы можете оставить основной шаблон CRTPBase неопределенный:

template<typename T> class CRTPBase; 

А затем частично специализировать это так:

template<template<typename, typename...> class TT, 
    typename SENDER, typename... ARGS> 
class CRTPBase<TT<SENDER, ARGS...>> 
{ 
    // ... 
}; 

Вот простая программа, которая показывает аргументы типа может быть получен в 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, "!"); 
} 

соответствует live example.

+0

Я пробовал это, но я не знаю, почему это не сработало :(Но спасибо – Manu343726

+0

@ Manu343726: Что значит «не работает»? –

+0

О, исправлено. – Manu343726

Смежные вопросы