我越来越"invalid conversion from `void*` to `std::complex<double>*"



我有下面的代码,

std::complex<double>** x;
x = calloc(10,sizeof(complex <double> *));

此代码编译失败,并显示以下错误消息。

error: invalid conversion from 'void*' to 'std::complex<double>*' [-fpermissive]

如何成功编译?为什么这个代码编译失败?

您正试图将C++当作C编写,这允许像这样危险的隐式转换。

要分配大小为10的动态数组,请使用

std::vector<std::complex<double>> numbers(10);

如果你真的想要一个指向第一个元素的指针

x = numbers.data();

在C++中,void *不会自动转换为其他指针(与C不同)。因此,如果在C++中使用malloc和族,则需要自己投射结果。

但是,您应该注意到malloc不理解C++的构造函数。因此,如果你想分配一个C++对象(例如不是C结构,或者更准确地说是POD),你应该使用new(以及相应的delete/delete[]),它可以正确地处理构造函数和析构函数。

或者,您可以使用标准库提供的众多结构中的一种,例如std::vector

问题

这个代码来自问题,…

x = calloc(10,sizeof(complex <double> *));

不合格有两个原因:

  • 与C不同,C++没有从void*和的隐式转换

  • 用C++new创建一个锯齿状数组已经够糟糕的了,用C级分配函数来创建锯齿状数组通常是令人讨厌的(除非某个函数需要调用)。

第一个要点是它在C++中编译失败的原因。


该怎么办

技术修复是使用强制转换,然后最好使用C++命名的强制转换,如static_castreinterpret_cast。两者在void*的转换实践中都很好。然而,在我看来reinterpret_cast更正确地表达了概念操作,因此我认为;d选择–如果我选择选角。

一个稍微好一点的解决方案是使用C++new而不是Ccalloc。对于new,您必须在末尾添加一个空括号,以获得calloc的保证零初始化。但主要的问题仍然是,每一个低水平的工作都很难(大量的工作)做好。

一个更好的通用解决方案是使用C++容器类。

标准库提供std::vector,使用它可以像这样构建锯齿状阵列:

typedef complex<double> Complex;
typedef vector<Complex> ComplexVec;
typedef vector<ComplexVec> ComplexVec2D;
ComplexVec2D x( 10 );

然后,由于std::vector是一个动态大小的数组,因此每个ComplexVec都可以被调整大小。


如果你真的想要一个矩阵,该怎么办

如果你真的想要一个矩阵,即一个相等长度的数组数组,那么考虑一个C++类,它只提供对单个向量的2D索引,而不是锯齿状数组。

在C++03风格中,它可以这样(即兴代码):

typedef complex<double> Complex;
class ComplexMatric
{
private:
vector<Complex> items_;
int             width_;
public:
Complex& operator()( int x, int y )
{ return items_[y*width_ + x]; }
Complex const& operator()( int x, int y ) const
{ return items_[y*width_ + x]; }
ComplexMatrix( int w, int h )
: items_( w*h )
, width_( w )
{}
};

你会这样使用它:

ComplexMatrix x( 10, some_height );

这包括进行正确的分配和解除分配,甚至支持通过分配进行复制。

免责声明:代码未经编译器处理。

不要使用calloc,而是尝试使用new[]运算符。这是动态创建数组的C++方法。

x = new complex<double>[10];

new[]返回一个指针,指向运算符后面的任何类型,在这种情况下,它是一个类型为complex<double>的指针,指向内部有10个元素的complex<double>数组。

不过,请注意,您必须使用delete[]运算符来解除分配内存(而不是free())。否则没人知道会发生什么:-)。

delete[] x;

假设x的类型为std::complex<double>*,则会出现此错误,因为calloc返回一个void指针。如果没有-fpermissive,则不允许隐式强制转换。因此,您必须在void*std::complex<double>*之间进行转换。然而,在C++中,建议使用new而不是malloccalloc,我个人建议您使用std::vector

相关内容

最新更新