How to specialize a template without copying and pasting the whole body of the class?

I wrote a simple moving average class that can be used with AVR.

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

But now I want to specialize this class for float without copying and pasting the whole body of the class and changing all T and Tsum to float and that I do not need to use two template parameters. Tsum is the type of the variable "sum", where all transmitted values โ€‹โ€‹of type T are summed. If T is 'uint8_t', it is recommended to use "uint32_t" for the sum, but for float or double there is no need to use the data type with higher precision, therefore, for this purpose I want only one parameter. I thought this might work like this:

typedef MovingAverage<float, float> MovingAverage<float>

or as follows:

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

But I was wrong, and I only found solutions where I need to write my code twice.

, , ? !

+5
2

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 { ... }
+8

// 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 (, , ), .

++, -not walk- ++ Templates: The Complete Guide. 15.1 15 .

+5

All Articles