CRTP+可变模板+提取CRTP子类参数

CRTP + variadic template + extract CRTP subclass parameters

本文关键字:提取 CRTP 子类 参数 CRTP+      更新时间:2023-10-16

Im当前正在实现一个通用事件类。事件处理程序有一个sender参数和数量可变的事件参数。因此事件类的声明如下:

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

为了允许某些实现细节,我需要事件的CRTP,如下所示:

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

并且CRTP基础需要知道事件参数。所以我尝试了一个模板模板参数:

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

但这不起作用(我使用GCC 4.8.1)

那么:提取CRTP参数的可变和非可变模板参数的最佳方法是什么

EDIT:另一种方法是直接通过CRTP模板(template<typename EVENT , typename EVENT_SENDER , typename... EVENT_ARGS> class CRTPBase;)提供事件参数,但我认为有一种方法可以直接做到这一点,而无需以明确的方式编写参数。

您可以不定义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, "!");
}

下面是相应的实例