5

我为移动平均线编写了一个简单的类,可以与 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> {};

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

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

4

2 回答 2

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 { ... }
于 2013-04-14T18:50:24.320 回答
5

您可以编写一个简单的特征类

// 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++ 模板:完整指南一书。第 15.1 节有超过 15 页的关于定义通用累积类模板的讨论。

于 2013-04-14T18:49:53.560 回答