我为移动平均线写了一个简单的类,它可以和AVR一起使用。
template<typename T, typename Tsum = int32_t>
class MovingAverage { ... }
但是现在我想把这个类专门用于float而不复制和粘贴整个类体并将所有T和Tsum更改为float并且我不需要使用两个模板参数。 Tsum是'sum'变量的类型,其中所有传递的T类型值都被总结。如果T是'uint8_t',最好使用'uint32_t'作为总和,但对于float或double,不需要使用具有更高精度的数据类型,因此我只需要一个参数用于此目的。我认为它可以这样工作:
typedef MovingAverage<float, float> MovingAverage<float>
或者这样:
template<>
class MovingAverage<float> : public MovingAverage<float, float> {};
但我错了,我找到了只需要编写代码两次的解决方案。
有没有办法只写一次这个类,然后按照我喜欢的方式专门化它? 提前谢谢!
答案 0 :(得分: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 { ... }
答案 1 :(得分:5)
你可以写一个简单的 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 ++模板,请运行-not walk-到最近的书店并获取书籍C++ Templates: The Complete Guide。第15.1节有关于定义泛型累积类模板的15页以上的讨论。