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

标签 c++ templates c++11 variadic-templates crtp

我目前正在实现一个通用事件类。事件处理程序有一个发送者参数和可变数量的事件参数。所以事件类的声明如下:

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

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

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

CRTP base 需要知道事件参数。所以我尝试使用模板模板参数:

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

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

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

编辑:另一种方法是直接通过 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, "!");
}

这里是对应的live example .

关于c++ - CRTP + 可变参数模板 + 提取 CRTP 子类参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17513744/

相关文章:

c++ - C++ 中的原始类型包装器既是 POD 又是可在表达式中构造的?

c++ - 快速了解 C++ 中的 const

c++应该在锁定下通知条件变量

templates - Odoo - 在日历 View 中使用模板?

c++ - 任何元编程方法可以为各种数量的模板参数生成重载?

c++11 - 在 std::function 上使用 typedef 来缩短它

c++ - 关闭 "' 寄存器的存储类说明符已弃用“警告

c++ - 使用 constexpr 进行常量初始化

c++ - 右值绑定(bind)与移动的结合

c++ - 来自用作模板参数的指针的类类型