На этом шаге мы рассмотрим особенности преобразований типов.
Конструкторы специализированных версий для типов float double и long double спроектированы так, чтобы безопасные преобразования типов (например, complex<float> в complex<double>) могли выполняться неявно, а потенциально рискованные преобразования (например, complex<long double> в complex<double>) были явными:
std::complex<float> cf; std::complex<double> cd; std::complex<long double> сld; . . . . . . std::complex<double> cd1 = cf; // OK: безопасное преобразование std::complex<double> cd2 = cld; // ОШИБКА: нет неявного преобразования std::complex<double> cd3(cld); // OK: явное преобразование
He существует конструкторов, создающих комплексное число по другим комплексным типам. В частности, нельзя преобразовать complex с целым типом в complex с типом float, double или long double. Впрочем, преобразования можно выполнять при передаче вещественной и мнимой частей в отдельных аргументах:
std::complex<double> cd; std::complex<int> ci; . . . . . std::complex<double> cd4 = ci; // ОШИБКА: небезопасное преобразование std::complex<double> cd5(ci); // ОШИБКА: нет явного преобразования std::complex<double> cd6(ci.real(),ci.imag()); // OK
К сожалению, операторы присваивания позволяют выполнять небезопасные преобразования. Они определены в виде шаблонов для всех типов, поэтому присваивание допустимо для любых комплексных типов (при возможности преобразования типа значения):
std::complex<double> cd; std::complex<long double> cld; std::complex<int> ci; . . . . . cd = ci; // OK cd = cld; // OK
Эта проблема также относится к функциям polar() и conj(). Например, следующая запись работает нормально:
std::complex<float> c2(std::polar(4.2,0.75)); // OK
С другой стороны, запись со знаком = не работает:
std::complex<float> c2 = std::polar(4.2,0.75); // ОШИБКА
Дело в том, что выражение std::polar(4.2,0.75) создает временный объект complex<double>, а неявное преобразование из complex<double> в complex<float> не определено.
X х; Y у(х); // Явное преобразование X х; Y у = х; // Неявное преобразование
На следующем шаге мы рассмотрим доступ к данным.