Рассмотрим следующий код
#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 + 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.
Других решений пока нет …