如何创建一个类似于泛型的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或fl2混合。模板是正确的吗,是否最好使用对象层次结构来定义顶级Num,例如,定义所有操作符并为每个受支持的类型设置一个子类?虽然我不认为这能解决混合类型的问题。
编辑1: res中的背景到Barry/lisyarus:我正在更改一个旧的代码库,它的类型定义如下:
template<typename a> struct NumT : public SomeSuperType<a> { mp::cpp_int val;};更改是以尽可能透明的方式在此float类型中添加对本机double和NumT类型的支持。理想情况下,NumT不应该改变除了改变装饰。val类型。现有代码只是在val上执行a + b和其他算术操作,而不是破坏现有的API内容是很重要的。i64 + fl1 + fl2 == 10046
发布于 2016-08-05 16:37:18
数值类型不同是有原因的(int、float等),试图将它们通用可能会出错。尽管如此,您可以使用std::common_type推断可以同时包含这两种类型的类型。
请注意,这里将失去“精确性”。例如,如果您有一个unsigned long long of 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;
}这些指纹:
10046https://stackoverflow.com/questions/38793786
复制相似问题