【问题标题】:specialize template with inner class template of a class template使用类模板的内部类模板专门化模板
【发布时间】:2018-08-24 18:10:51
【问题描述】:

我有一个蓝牙库,它将link_layer 定义为最低协议层,它在radio 之上实现了链路层协议。 link_layer 本身是一个模板,允许使用不同的 radio 实现。 radio 本身也是一个模板,以允许不同的基本配置(例如缓冲区大小)。

许多无线电实现可以共享一些共同的行为,例如buffers。所以一些无线电实现通过继承它们(CRTP)结合了很多实现。

现在我需要buffer 实现中的一些细节,这些细节取决于实际的radio 实现(mapping 在内存中和无线 PDU 布局之间)。显而易见的解决方案,将 mapping 定义为收音机中的类型不起作用,因为收音机继承了 buffer 实现,并且在 buffer 模板实例化时,radio 因此仍然是不完整的输入。

此问题的推荐解决方案是将映射定义为 trait 类型,并将 trait 专门用于所有 radio 实现。这很有效,因为有一个合理的默认值,适用于很多 radios。

除了buffer,还有一个不同的实现细节(加密),我通过继承将其混合到radio 实现中。在其中一种情况下,我需要从上面专门化 trait,该类型本身又是一个模板。我使用factory 混合了不同的加密支持类型,它定义了radio 模板作为结果。这是该场景的简短草图:

#include <type_traits>

template < typename OtherOption, template < typename > class Radio >
struct link_layer : Radio< OtherOption >
{
};

template < class ConfiguredRadio >
struct trait
{
    using mapping = int;
};

template < typename ConfiguredRadio >
struct buffers
{
    using mapping = typename trait< ConfiguredRadio >::mapping;
};

template < typename Base >
struct radio_factory
{
    template < typename T >
    struct radio : buffers< radio< T > >, Base
    {
    };
};

struct radio_without_enryption_base {};

template < typename Option >
struct radio_with_enryption_base {};

template < typename Option, typename T >
struct trait<
    typename radio_factory<
        radio_with_enryption_base< Option >
    >::template radio< T >
>
{
    using mapping = short;
};

template < typename OtherOption >
using ll_without_encryption = link_layer<
    OtherOption,
    radio_factory< radio_without_enryption_base >::template radio >;

template < typename OtherOption >
using ll_with_encryption = link_layer<
    OtherOption,
    radio_factory< radio_with_enryption_base< OtherOption > >::template radio >;

int main()
{
    static_assert( std::is_same< ll_without_encryption< int >::mapping, int >::value, "" );
    static_assert( std::is_same< ll_with_encryption< int >::mapping, short >::value, "" );
}

我尝试过的所有编译器都抱怨,trait&lt;&gt; 的部分特化包含不可推导的模板参数。是否可以使用模板类型专门化模板,即另一个模板的内部类型?如果没有,可能的解决方法是什么?

【问题讨论】:

    标签: c++ traits crtp


    【解决方案1】:

    typename someClass&lt;T&gt;::type 不可演绎。

    解决方法是将类定义为内部类型:

    namespace detail
    {
        template<typename T, typename Base>
        struct radio : buffers<radio<T, Base>>, Base
        {
        };
    }
    
    template < typename Base >
    struct radio_factory
    {
        template <typename T>
        using radio = details::radio<T, Base>; // Same interface as before
    };
    
    template <typename T, typename Option>
    struct trait<detail::radio<T, radio_with_enryption_base<Option>>>
    {
        using mapping = short;
    };
    

    Demo

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-13
      • 1970-01-01
      相关资源
      最近更新 更多