将模板类型 T 修改C++为 "long T" ?

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

本文关键字:long C++ 修改 类型      更新时间:2023-10-16

是否有任何方法将乘法返回的精度加倍(以避免溢出)?

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

类似:

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

因此,无论给定'int', 'long'或'double',乘法运算都会返回'long int', 'long long'或'long double'。

这是一个一般性问题。我通过在内部使用double来解决它。但我的问题是,在c++中是否有任何机制可以将类型提升为其"长"变体?

一个可能的解决方案是定义你自己的类型特征:

template<typename T>
struct add_long { typedef T type; };
template<>
struct add_long<int> { typedef long int type; };
template<>
struct add_long<double> { typedef long double type; };
template<>
struct add_long<long int> { typedef long long int type; };
// And so on...

你可以这样在你的类中使用它:

template<class T>
class MyClass {
public:
    typedef typename add_long<T>::type longT;
    longT multiply (longT a, longT b) { return a * b; }
};

这里有一个小测试:

#include <type_traits>
int main()
{
    MyClass<int> m;
    auto l = m.multiply(2, 3);
    static_assert(std::is_same<decltype(l), long int>::value, "Error!");
}

@Andy有正确的答案,效果很好。但是,对于那些希望在MyClass实例化为没有'long'值的类型时出现编译时错误的人,我将其与@SteveJessop的优秀注释结合起来,给出以下解决方案:

// --- 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; };

'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; }
}

MyClass使用示例:

MyClass<float> my;
printf("result = %lfn", my.multiply(3.4e38, 3.4e38));
相关文章: