通用的Num类

时间:2016-08-05 16:20:22

标签: c++ c++11

如何创建一个通用的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无法与fl1或{{1}混合使用}}。 模板在这里是正确的吗,使用定义顶级fl2的对象层次结构是否更好?它定义了所有运算符,并为每种支持的类型都有一个子类?虽然我不认为能解决混合类型的问题。

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

Num

更改是以尽可能透明的方式在此template<typename a> struct NumT : public SomeSuperType<a> { mp::cpp_int val;}; 类型中添加对原始floatdouble类型的支持。 理想情况下,NumT不应该改变,而不是改变decl。类型NumT。 现有代码只执行vala + b上的其他算术运算,而不是破坏现有的API内容非常重要。 val

1 个答案:

答案 0 :(得分:2)

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

请注意,这里会丢失“precision”。例如,如果您有unsigned long long 1434263462343574573ULL,请将其转换为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