Я получаю «неверное преобразование из` void * `в` std :: complex & lt; double & gt; * & quot;

У меня есть следующий код ниже,

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

Этот код не удалось скомпилировать со следующим сообщением об ошибке.

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

Как я могу успешно скомпилировать? Почему этот код не компилируется?

0

Решение

В C ++ void * не приводится автоматически к другим указателям (в отличие от C). Так что если вы используете malloc и семью в C ++, вам нужно привести результат самостоятельно.

Тем не менее, вы должны отметить, что malloc не понимает конструкторы C ++. Поэтому, если вы хотите выделить объект C ++ (например, не структуру C или, точнее, POD), вам следует использовать new (а также delete/delete[] соответственно) который правильно заботится о конструкторах и деструкторах.

Кроме того, вы можете использовать одну из многих структур, предоставляемых стандартной библиотекой, например: std::vector,

4

Другие решения

Вы пытаетесь написать C ++, как если бы это был C, который допускает опасные неявные преобразования, подобные этой.

Чтобы выделить динамический массив размером 10, используйте

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

и, если вы действительно хотите указатель на первый элемент

x = numbers.data();
6

Этот код из вопроса,…

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

это плохо по двум причинам:

  • в отличие от C, C ++ не имеет неявного преобразования от void*, а также

  • создание зубчатого массива с помощью C ++ new достаточно плохо, делать это с помощью функций выделения уровня С — это вообще мерзость (кроме случаев, когда это требуется для какой-то функции, которую нужно вызвать).

Первый пункт — почему он не компилируется в C ++.


Чисто технический исправить это использовать приведение, а затем предпочтительно C ++ с именем приведение, такое как static_cast или же reinterpret_cast, Оба отлично работают на практике для преобразования из void*, Однако на мой взгляд reinterpret_cast выражает концептуальную операцию более правильно, поэтому я бы выбрал это — если Я решил сыграть.

Немного лучшим решением является использование C ++ new вместо С calloc, С new Вы должны добавить пустые скобки в конце, чтобы получить гарантированную нулевую инициализацию calloc, Но главная проблема по-прежнему заключается в том, что каждый низкий уровень и трудно (много работы), чтобы получить право.

Гораздо лучшим общим решением является использование класса контейнера C ++.

Стандартная библиотека предлагает std::vector, с помощью которого зубчатый массив может быть построен следующим образом:

typedef complex<double> Complex;
typedef vector<Complex> ComplexVec;
typedef vector<ComplexVec> ComplexVec2D;

ComplexVec2D x( 10 );

Тогда каждый ComplexVec можно просто изменить размер, так как std::vector динамически изменяемый массив


Если вы действительно хотите матрица, то есть массив массивов равной длины, тогда вместо зубчатого массива рассмотрим класс C ++, который просто обеспечивает двумерную индексацию в одном векторе.

В стиле 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 );

Это включает в себя правильное распределение и освобождение, и даже поддержку копирования по назначению.

Отказ от ответственности: код не тронут руками компилятора.

2

Вместо того, чтобы использовать callocпопробуйте использовать new[] оператор вместо. Это способ C ++ для динамического создания массива.

x = new complex<double>[10];

new[] возвращает указатель на любой тип, следующий за оператором, в данном случае это указатель с типом complex<double> который указывает на массив complex<double> с 10 элементами внутри.

Знайте, однако, вы должны использовать delete[] оператор для освобождения памяти (не free()). Иначе никто не знает, что произойдет :-).

delete[] x;
1

Предполагая ваш x имеет тип std::complex<double>*, вы получаете эту ошибку, потому что calloc возвращает void указатель. Без -fpermissive неявные приведения не допускаются. Итак, вам придется бросить между void* а также std::complex<double>*, Тем не менее, в C ++ рекомендуется использовать new вместо malloc или же callocи лично я бы порекомендовал вам использовать std::vector,

0
По вопросам рекламы [email protected]