Implicit Conversion (Coercion)
Implicit conversion (aka. type coercion) happens when C++ expects a value of one type, and you give a value of different type:
- If the value can be converted — implicit conversion occurs.
- If the value cannot be converted — compile error occurs.
Note that type conversion produces a new value of the desired type and DOES NOT change the value or type of the object being converted (learncpp.com).
Numeric promotions
Numeric promotion converts a smaller data type to a larger data type (e.g. float to double), but the rule is only applied to certain data types. (For other data types that are not covered by numeric promotion, see numeric conversion below.)
Numeric promotions are guaranteed to preserve the value before and after promotion.
Integral promotions
signed charandsigned short— can be converted tointunsigned charandunsigned short— can be converted tointORunsigned int(depending on whether the architecture'sintcan hold the entire range of the original type)bool— can be converted toint(false becomes 0, true becomes 1)
Floating-point promotions
float— can be converted todouble
Numeric conversions
Numeric conversion works like numeric promotion, but applies to a wider range of data types. (The distinction between numeric promotion and conversion is "mostly academic," but matters in function overload resolution, learncpp.com.)
- an integer type — can be converted to any other integer types (e.g.
inttoshort, orinttolong) - a floating-point type — can be converted to any other floating-point types (e.g.
doubletofloat, ordoubletolong double) - an integer type — can be converted to any floating-point types (e.g.
inttodouble) - a floating-point type — can be converted to any integer types (e.g.
doubletoint) - an integer type or a floating-point type — can be converted to
bool(non-zero value becomes true, zero value becomes false)
Narrowing conversions
Note that conversions from "larger" or "more precise" data types to "smaller" or "less precise" data types are called narrowing conversions.
You may lose data/precision in this case. For example, when you store a double value 3.123 to an int, you will get 3.
Arithmetic conversions
Operations with most binary operators (e.g. +, -, <, >, &&) normally require that the operands' types to be the same.
If the types are not the same, then the operand with the "lower priority" is converted to match the type of the operand with the "higher priority" (e.g. operating an int with a double will produce a double value):
long double(highest)doublefloatunsigned long longlong longunsigned longlongunsigned intint(lowest)
Pointer conversions
- pointer to a subclass — can be converted as pointer to its superclass ("upcasting")
- pointer to any type — can be converted as pointer with type
void* - pointer with type
void*— can be converted as pointer to any type (with explicit cast) - zero integer expression — can be converted as the null pointer
Reference conversions
- reference to a subclass — can be converted as reference to its superclass ("upcasting")
References
- 8.1 — Implicit type conversion (coercion) — https://www.learncpp.com/cpp-tutorial/implicit-type-conversion-coercion/
- 8.2 — Floating-point and integral promotion — https://www.learncpp.com/cpp-tutorial/floating-point-and-integral-promotion/
- 8.3 — Numeric conversions — https://www.learncpp.com/cpp-tutorial/numeric-conversions/
- 8.11 — Function overload resolution and ambiguous matches — https://www.learncpp.com/cpp-tutorial/function-overload-resolution-and-ambiguous-matches/
- Standard conversions — https://docs.microsoft.com/en-us/cpp/cpp/standard-conversions?view=msvc-170