【问题标题】:CRTP + variadic template + extract CRTP subclass parametersCRTP + 可变参数模板 + 提取 CRTP 子类参数
【发布时间】:2013-07-07 16:01:04
【问题描述】:

我目前正在实现一个通用事件类。事件处理程序有一个 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 参数的可变参数和非可变参数模板参数的最佳方法是什么?

编辑: 另一种方法是直接通过 CRTP 模板 (template&lt;typename EVENT , typename EVENT_SENDER , typename... EVENT_ARGS&gt; class CRTPBase;) 提供事件参数,但我认为有一种方法可以直接执行此操作,而无需以显式方式编写参数.

【问题讨论】:

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


    【解决方案1】:

    您可以保留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

    【讨论】:

    • 我试过这个,但我不知道为什么它不起作用:(但是谢谢
    • 哦,已修复。伟大的!谢谢!
    • 为什么断言不会触发?
    • 它不应该开火。你为什么会期待它? event::type 真的是一个元组 所以它们是相同的类型。这不会编译的唯一原因是因为类型是私有的,因此无法从 main 访问。
    猜你喜欢
    • 2021-03-30
    • 1970-01-01
    • 2016-04-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-30
    • 1970-01-01
    相关资源
    最近更新 更多