如何在不复制和粘贴整个类体的情况下专门化模板?

use*_*245 5 c++ templates template-specialization

我为移动平均线写了一个简单的类,它可以和AVR一起使用.

template<typename T, typename Tsum = int32_t>
class MovingAverage { ... }
Run Code Online (Sandbox Code Playgroud)

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

typedef MovingAverage<float, float> MovingAverage<float>
Run Code Online (Sandbox Code Playgroud)

或者这样:

template<>
class MovingAverage<float> : public MovingAverage<float, float> {};
Run Code Online (Sandbox Code Playgroud)

但我错了,我找到了只需要两次编写代码的解决方案.

有没有办法只写一次这个类,然后按照我喜欢的方式专门化它?提前致谢!

Dan*_*rey 8

如果你想要不同的默认类型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 { ... }
Run Code Online (Sandbox Code Playgroud)


Tem*_*Rex 5

你可以编写一个简单的traits类

// 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.
Run Code Online (Sandbox Code Playgroud)

然后在类模板中提取此类型

template<typename T, typename Tsum = typename sum_type<T>::type>
//                                   ^^^^^^^^ <-- dependent type disambiguation
class MovingAverage { ... };
Run Code Online (Sandbox Code Playgroud)

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

如果您认真使用C++模板,请运行-not walk-到最近的书店并获取" C++模板:完整指南"一书.第15.1节有关于定义泛型累积类模板的15页以上的讨论.