【问题标题】:How to specialize a template without copying and pasting the whole class body?如何在不复制和粘贴整个类体的情况下专门化模板?
【发布时间】:2013-04-14 18:42:50
【问题描述】:

我为移动平均线编写了一个简单的类,可以与 AVR 一起使用。

template<typename T, typename Tsum = int32_t>
class MovingAverage { ... }

但是现在我想将这个类专门用于浮点而不复制和粘贴整个类主体并将所有 T 和 Tsum 更改为浮点,并且我不需要使用两个模板参数。 Tsum 是“sum”变量的类型,其中所有传递的 T 类型的值都被汇总。如果 T 是 'uint8_t',最好使用 'uint32_t' 作为总和,但对于 float 或 double,不需要使用精度更高的数据类型,因此我只需要一个参数。我认为它可以这样工作:

typedef MovingAverage<float, float> MovingAverage<float>

或者这样:

template<>
class MovingAverage<float> : public MovingAverage<float, float> {};

但我错了,我只找到了我必须编写两次代码的解决方案。

有没有办法只编写一次课程,然后以我喜欢的方式对其进行专门化? 提前致谢!

【问题讨论】:

    标签: c++ templates template-specialization


    【解决方案1】:

    如果您希望Tsum 有不同的默认类型,这应该外包给另一个可以指定的类,例如:

    template< typename, typename = void >
    struct DefaultSum { using type = int32_t; };
    
    template< typename T >
    struct DefaultSum< T, typename std::enable_if<
      std::is_floating_point< T >::value
    >::type >
    { using type = T; };
    
    template<typename T, typename Tsum = typename DefaultSum<T>::type >
    class MovingAverage { ... }
    

    【讨论】:

    • 谢谢你,@Daniel!这非常好,并且可以与 gcc 完美配合。不幸的是,我发现我没有为 avr-gcc 安装 boosts type_traits 版本。目前我正在谷歌搜索一个可安装的 debian 包来让它工作。否则,我将需要的部分从我的 x86_64 安装复制到 avr-gcc 的包含目录。
    【解决方案2】:

    你可以写一个简单的traits class

    // general version
    template<typename T>
    struct sum_type
    {
        typedef int32_t type;
    };
    
    // specialized version
    template<>
    struct sum_type<float>
    {
        typedef float type;
    };
    
    // repeat for double, the solution from @DanielFrey is even more sophisticated 
    // as it specializes all floating point types in one sweep.
    

    然后在你的类模板中提取这个类型

    template<typename T, typename Tsum = typename sum_type<T>::type>
    //                                   ^^^^^^^^ <-- dependent type disambiguation
    class MovingAverage { ... };
    

    请注意,这仅适用于您的 MovingAverage 具有定期参数化的实现。如果您实际上正在为float 做一些特殊的事情(例如,重写表达式以处理浮点运算的非关联字符),那么您需要做更多的工作。

    如果您对使用 C++ 模板很认真,请运行 - 而不是步行 - 到最近的书店并获取书籍 C++ Templates: The Complete Guide。第 15.1 节有超过 15 页的关于定义通用累积类模板的讨论。

    【讨论】:

    • @DanielFrey 这本书也很好读,很有教学性,迫不及待想要一个 C++11 版本。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-13
    • 1970-01-01
    • 1970-01-01
    • 2015-06-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多