Шаг 414.
Библиотека STL. Числовые типы. Операции над комплексными числами. Неявные преобразования типов

    На этом шаге мы рассмотрим особенности преобразований типов.

    Конструкторы специализированных версий для типов 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 у = х; // Неявное преобразование

    На следующем шаге мы рассмотрим доступ к данным.




Предыдущий шаг Содержание Следующий шаг