我有很多具有此类签名的功能:
//libraries I can't change
void f1(double *x);
void f2(double *x1, double *x2);
...
许多使用它们的代码:
//my code
double x; ... f1(&x);
double x1[] = ...; double x2 = ...; f2(x1, &x2);
...
由于某些原因,我决定在我的代码中使用特殊类而不是普通双打:
struct DoubleClass {
double x_;
...
//constructors, overloaded arithmetic operators and casts to double
};
这个DoubleClass的行为类似于我想要的一些额外功能。在内存中,DoubleClass与double相同。它只有1个成员和sizeof(DoubleClass)== sizeof(double)。 所以我想用我的代码重新声明所有双打
#define double DoubleClass
但我无法编译代码,因为没有从DoubleClass *到double *的转换。我不能改变函数f1,f2。所以我想问一下,我是否可以某种方式定义从DoubleClass *到double *的隐式转换,或者可能有一些技巧可以实现它。
答案 0 :(得分:1)
对于f1()
和f2()
的第二个参数,您可以覆盖operator&
以返回double*
:
struct DoubleClass {
double x_;
...
double* operator&() { return &x_; }
};
DoubleClass x = ...;
f1(&x);
DoubleClass x2 = ...;
f2(..., &x2);
但DoubleClass
中没有运算符重载可以帮助您使用f2()
的第一个参数,因为DoubleClass[]
数组与double[]
数组完全不同。需要显式的类型转换:
DoubleClass x1[] = ...;
f2(reinterpret_cast<double*>(&x1[0]), ...);
或者使用带转换运算符的包装器:
template <const int N>
struct DoubleClassArray
{
DoubleClass arr_[N];
...
operator double*() { return arr_; }
};
DoubleClassArray<...> x = ...;
f2(x1, ...);
所以我想重新声明我的代码中的所有双打类似
#define double DoubleClass
我不建议这样做。但如果你这样做,你必须确保保护double
内的DoubleClass
,否则它也会被改变。定义重载会更安全:
struct DoubleClass {
double x_;
...
//DO NOT override operator&!
};
void f1(DoubleClass *x) { f1(reinterpret_cast<double*>(x); }
void f2(DoubleClass *x1, DoubleClass *x2) { f2(reinterpret_cast<double*>(x1), reinterpret_cast<double*>(x2); }
...
DoubleClass x; ...
f1(&x);
DoubleClass x1[] = ...;
DoubleClass x2 = ...;
f2(x1, &x2);
答案 1 :(得分:0)
你能检查减去正常的双值而不是重载运算符吗?如果减去的两个双精度数为0,则它们恰好相等*
machine precision floating point例如,机器精度是一个挑剔的事情*