Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Modify C++ template type T to be "long T"?

Is there any way to double the precision returned by multiply (to avoid overflow)?

template<class T> class MyClass {
     T multiply (T a, T b) { return a * b; }
}

Something like:

long T multiply (T a, T b) { return a * b; }

So that whether 'int', 'long', or 'double' was given, a 'long int', 'long long', or 'long double' would be returned from multiply.

This is a general question. I'm working around it by using a double internally. But my question is whether there is any mechanism to promote a type to its "long" variant in C++?

like image 958
Brent Faust Avatar asked Mar 07 '13 23:03

Brent Faust


1 Answers

@Andy has the right answer, which works quite well. But for those who want a compile-time error if MyClass is instantiated with a type for which there is no 'long' value, I've combined it with @SteveJessop's excellent comment to give the following solution:

// --- Machinery to support double-precision 'T' to avoid overflow in method 'multiply' ---
// Note: uncomment typedef if don't want compile-time errors 
// when no "long" type exists
// ----
template<typename T>
struct add_long { /*typedef T type;*/ };

template<> struct add_long<int8_t>   { typedef int16_t  type; };
template<> struct add_long<int16_t>  { typedef int32_t  type; };
template<> struct add_long<int32_t>  { typedef int64_t  type; };
template<> struct add_long<uint8_t>  { typedef uint16_t type; };
template<> struct add_long<uint16_t> { typedef uint32_t type; };
template<> struct add_long<uint32_t> { typedef uint64_t type; };

template<> struct add_long<float>    { typedef double        type; };
template<> struct add_long<double>   { typedef long double   type; };

Example usage of 'longT':

template<class T> class MyClass
{
    // Note: a compiler error on the next line means that 
    //       class T has no double-precision type defined above.
    typedef typename add_long<T>::type longT;
public:
    longT multiply (T a, T b) { return longT(a) * b; }
}

Example Usage of MyClass:

MyClass<float> my;
printf("result = %lf\n", my.multiply(3.4e38, 3.4e38));
like image 162
Brent Faust Avatar answered Oct 07 '22 07:10

Brent Faust