将模板类型 T 修改C++为 "long T" ?
Modify C++ template type T to be "long T"?
是否有任何方法将乘法返回的精度加倍(以避免溢出)?
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));
相关文章:
- 如何在 C 中正确使用 libiconv 使其不会报告"Arg list too long"?
- 不能在初始值设定项列表中将非常量表达式从类型 'int' 缩小到'unsigned long long'
- 在C++中使用GDAL可以将图像的像素坐标转换为lat,long吗
- <Windows>为什么 std::thread::native_handle 返回类型为"long long unsigned int"的值,而不是 void*(又名 HANDLE)?
- 错误:隐式转换更改符号:'int'到'unsigned long'
- 这句话是什么意思 - " vector<long long> distance(n, std::numeric_limits<long long>::max()); "?
- C ++分割错误,为什么使用"long long"我没有得到答案?
- 对 '(const Y) (int&, std::mersenne_twister_engine<long unsigned int,
- 从 long 转换C++位集构造函数的复杂性是多少?
- 自动类型默认为 int 而不是 long
- 错误:'class std::unique_ptr<std::set<long unsigned int> >'没有名为 'size' 的成员
- C++ 我应该如何解释函数参数long(*pPointer)(OtherClass *const, long)?
- 以0开头的值初始化long-long会导致奇怪的值
- "1L << count"是什么意思?如何使用超出"unsigned long long int? "范围的语句编号打印?
- cudaMallocManaged with vector<complex<long double> > C++ - NVIDIA CUDA
- 为什么我的函数返回 long long 返回 705032704?
- C++11 模板函数"implicity"将位集<N>转换为"unsigned long"
- 替换 c++ 中的 c 样式强制转换 (long&)
- 如何在 Turbo C++ 3.2 编译器中使用 long long 关键字
- Visual studio 2013 和 g++ 7.1 中将 int 和 long 类型相乘时的 c++ 差异行为