包含两个双精度的类是 std::complex 参数的有效替代品<double>吗?

Is a class containing two doubles a valid replacement for std::complex<double> parameters?

本文关键字:lt gt 替代品 double 参数 双精度 std 包含两 complex 有效      更新时间:2023-10-16

一个没有虚方法和只有两个double数据成员的简单类可以安全地被认为是std::complex<double>参数的"临时替代品"吗?

换句话说,假设有一个函数期望一个数组的std::complex<double>,可以使用上述类代替?

我尝试了以下代码,它似乎在Visual c++ 2010 SP1编译器上工作得很好。但是,我想知道这是特定于实现的东西,还是标准正式支持的东西。


可编译代码如下:

#include <iostream>
#include <complex>
#include <vector>
using namespace std;
class Point {
public:
    Point(double x, double y) 
        : _x(x), _y(y) { }
    // ... some non-virtual methods ...
private:
    double _x;
    double _y;
};
void f(const complex<double>* data, int count) {
    for (int i = 0; i < count; ++i) {
        cout << "(" << data[i].real() << ", " 
             << data[i].imag() << ") ";
    }
    cout << endl;
}
int main() {
    vector<Point> points;
    points.push_back(Point(11.0, 22.0));
    points.push_back(Point(33.0, 44.0));
    points.push_back(Point(55.0, 66.0));
    f(reinterpret_cast<const complex<double>*>(points.data()),
      static_cast<int>(points.size()));
}
输出:

C:TempCppTests>cl /EHsc /W4 /nologo test.cpp
test.cpp
C:TempCppTests>test.exe
(11, 22) (33, 44) (55, 66)

是的,它是安全的。

Point类不是POD(因为构造函数),但它是一个"标准布局类"。complex<double>类型在标准中定义了布局

虽然你有工作,似乎是安全的所有帐户,我会去一个更干净的解决方案。创建一个可以将Point类型强制转换为std::complex<double>类型的操作符。

class Point {
public:
    Point(double x, double y) 
        : _x(x), _y(y) { }
    operator std::complex<double> () const { return std::complex<double>(_x, _y); }
private:
    double _x;
    double _y;
};

您可以将函数f重构为两个:

void f(std::complex<double> const& data) {
    cout << "(" << data.real() << ", " 
       << data.imag() << ") ";
}
void f(const Point* points, int count) {
    for (int i = 0; i < count; ++i) {
        f(points[i]); // Call the first function using the cast operator.
    }
    cout << endl;
}

main可以看起来更干净一点。

int main() {
    vector<Point> points;
    points.push_back(Point(11.0, 22.0));
    points.push_back(Point(33.0, 44.0));
    points.push_back(Point(55.0, 66.0));
    f(points.data(), static_cast<int>(points.size()));
}