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)
但我错了,我找到了只需要两次编写代码的解决方案.
有没有办法只写一次这个类,然后按照我喜欢的方式专门化它?提前致谢!
如果你想要不同的默认类型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)
你可以编写一个简单的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页以上的讨论.