.. namespace:: units Conversions and Casting ======================= Programmers who are not full-time programming language geeks **hate lack of implicit conversions** that they consider reasonable. Violate their expectations for reasons they consider hypothetical problems and you get disuse. In type terms, I usually **translate "reasonable" to "not narrowing" aka "not loosing information."** That can reasonably easily be explained to non-language-experts. -- *Bjarne Stroustrup* The library tries to follow the above principle and at the same time is also consistent with conversions of ``std::chrono::duration``. No Conversions -------------- No conversions (either implicit or explicit) are available across quantities of different dimensions:: si::length d1 = 1q_s; // Compile-time error si::length d2(1q_s); // Compile-time error auto d3 = quantity_cast(1q_s); // Compile-time error Implicit -------- Implicit conversions are allowed only across quantities of the same dimension: - for integral types with ratios that guarantee no precision loss:: si::length d1 = 1q_km + 1q_m; // OK si::length d2 = 1q_km + 1q_m; // OK si::length d3 = 1q_km + 1q_m; // Compile-time error si::length d4(1q_km + 1q_m); // Compile-time error si::length d5 = 1q_m + 1q_ft; // Compile-time error si::length d6(1q_m + 1q_ft); // Compile-time error - from an integral to a floating-point representation even in case of a truncating ratio:: si::length d7 = 1q_km + 1q_m; // OK si::length d8 = 1q_m + 1q_ft; // OK - when both sides use a floating-point representation:: si::length d9 = 1.23q_m; // Compile-time error si::length d10 = 1.23q_m; // OK Explicit -------- Explicit conversions are available with the `quantity_cast` and `quantity_point_cast` function templates. They are especially useful to force a truncating conversion across quantities of the same dimension for integral representation types and ratios that may cause precision loss:: si::length d1 = quantity_cast(1km + 1m); // OK si::length d2 = quantity_cast(1s); // Error .. seealso:: Explicit casts are also really useful when working with legacy interfaces. More information on this subject can be found in :ref:`Working with Legacy Interfaces` chapter. Quantity Cast Overloads ^^^^^^^^^^^^^^^^^^^^^^^ `quantity_cast` comes with several overloads: .. code-block:: :linenos: std::cout << "Distance: " << quantity_cast>(d) << '\n'; std::cout << "Distance: " << quantity_cast(d) << '\n'; std::cout << "Distance: " << quantity_cast(d) << '\n'; `quantity_cast` in line #1 takes a specific target `quantity` type to which an explicit cast should be performed. This option will change multiple quantity properties at once (unit, representation, etc). However, it is also possible to force only one property at once and leave the rest intact: - line #2 forces only a specific destination unit type, - line #3 sets only a representation type to the type provided by the user. `quantity_point_cast` takes anything that works for `quantity_point` or a specific target `quantity_point`:: std::cout << "Point: " << quantity_point_cast(d) << '\n'; .. seealso:: For more information on conversion and casting and on how to extend the above "integral" vs "floating-point" logic please refer to the :ref:`Using Custom Representation Types` chapter.