Generic Num class

Generic Num class

本文关键字:class Num Generic      更新时间:2023-10-16

如何创建一个类似num的泛型类,以便唯一重要的是存在相关的成员函数/运算符?

我读过SFINAE,但老实说我不明白。

#include <iostream>
template<typename T>
class Numeric {
  const T a;
public:
  Numeric(const T &v) : a(v) {}
  T operator+(const Numeric<T> &b) {
    return a + b.a;
  }
};
int main() {
  Numeric<float> fl1(35.5);
  Numeric<float> fl2(10.5);
  Numeric<uint64_t> i64(10000);
  std::cout << (i64 + fl1 + fl2) << std::endl;
  return 0;
}

这里,fl1 + fl2可以,但由于运算符定义T是同一类型,因此i64不能与fl1fl2混合。模板是正确的吗?使用定义顶级Num的对象层次结构(例如,它定义了所有运算符并为每个支持的类型都有一个子类(会更好吗?尽管我认为这并不能解决混合类型的问题。

第1版:Barry/lisyarus背景:我正在更改一个旧的代码库,它的类型定义如下:

template<typename a> struct NumT : public SomeSuperType<a> { mp::cpp_int val;};

更改是以尽可能透明的方式在此NumT类型中添加对本机floatdouble类型的支持。理想情况下,NumT的变化不应超过decl。CCD_ 10的类型。现有的代码只是在val上执行a + b和其他算术运算,而不是破坏现有的API内容是很重要的。i64 + fl1 + fl2 == 10046

数字类型不同(intfloat等(是有原因的,试图将它们通用化可能会出错。尽管如此,您可以使用std::common_type来推导可以同时包含这两者的类型。

请注意,此处将丢失"精度">。。例如,如果您的unsigned long long1434263462343574573ULL,则将其转换为double将丢失一些有效数字。

#include <iostream>
#include <type_traits>
template<typename T>
class Numeric {
    const T a;
public:
    Numeric(const T &v) : a(v) {}
    T get() const { return a; }
};
template<typename T, typename U>
Numeric<typename std::common_type<T, U>::type> //With C++14, do std::common_type_t<T, U>
operator + (const Numeric<T>& a, const Numeric<U>& b) {
    return a.get() + b.get();   //Works because of the converting constructor
}
template<typename T>
std::ostream& operator << (std::ostream& os, const Numeric<T>& n){
    os << n.get();
    return os;
}
int main() {
    Numeric<float> fl1(35.5);
    Numeric<float> fl2(10.5);
    Numeric<uint64_t> i64(10000);
    std::cout << (i64 + fl1 + fl2) << std::endl;
    return 0;
}

此打印:

10046