std :: сложная проблема инициализации

Рассмотрим следующий код

#include <complex>
#include <iostream>

int main(int argc, char **argv)
{
std::complex<double> a = 1+1i;
std::cout<<"a ="<<a<<"\n";
return 0;
}

Когда я компилирую с использованием Apple LLVM версии 8.0.0 (clang-800.0.42.1) и получаю вывод

a =(1,0)

Может кто-нибудь объяснить, почему мнимая часть инициализируется с нуля?

1

Решение

1 + 1i использует расширение (GCC), которое создает типы, аналогичные / эквивалентные C99 _Complex int тип. Этот тип может быть преобразован в реальный тип, такой как int или же double, std::complex не совместим с _Complex, он не имеет конструкторов для создания std::complex из _Complex (*). Но std::complex<T> есть конструктор, который принимает T, Это запускает вышеупомянутое преобразование _Complex -> T -> std::complex<T>,

Таким образом, код в ОП эквивалентен:

#include <complex>
#include <iostream>

int main()
{
double d = 1+1i;
std::complex<double> a = d;
std::cout<<"a ="<<a<<"\n";
return 0;
}

Мнимая часть 1 + 1i отбрасывается при преобразовании в double,


Чтобы предотвратить такие неожиданности, попробуйте скомпилировать с предупреждениями и -pedantic, Этот пример, кажется, является одним из немногих мест, где Clang добавляет дополнительное предупреждение с -pedantic флаг (для gcc, -pedantic изменяет вывод предупреждения во многих контекстах):

prog.cc:6:19: предупреждение: мнимые константы являются расширением GNU [-Wgnu-мнимая-константа]
двойной d = 1 + 1i;

(*) IIRC, std::complex был введен в C ++ 98, в то время как _Complex был введен в C99.

2

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

Других решений пока нет …

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