cpp/language/implicit conversion

Implicit conversions are performed whenever an expression of some type is used in context that does not accept that type, but accepts some other type ; in particular: The program is well-formed (compiles) only if there exists one unambiguous implicit conversion sequence from to.
 * when the expression is used as the argument when calling a function that is declared with as parameter;
 * when the expression is used as an operand with an operator that expects ;
 * when initializing a new object of type, including statement in a function returning ;
 * when the expression is used in a statement ( is integral type);
 * when the expression is used in an statement or a loop ( is ).

If there are multiple overloads of the function or operator being called, after the implicit conversion sequence is built from to each available,  rules decide which overload is compiled.

Note: in arithmetic expressions, the destination type for the implicit conversions on the operands to binary operators is determined by a separate set of rules:.

Order of the conversions
Implicit conversion sequence consists of the following, in this order: @1@ zero or one standard conversion sequence; @2@ zero or one user-defined conversion; @3@ zero or one standard conversion sequence (only if a user-defined conversion is used).

When considering the argument to a constructor or to a user-defined conversion function, only one standard conversion sequence is allowed (otherwise user-defined conversions could be effectively chained). When converting from one non-class type to another non-class type, only a standard conversion sequence is allowed.

A standard conversion sequence consists of the following, in this order: @1@ zero or one conversion from the following set: lvalue-to-rvalue conversion, array-to-pointer conversion, and function-to-pointer conversion; @2@ zero or one numeric promotion or numeric conversion;

@4@ zero or one qualification conversion.

A user-defined conversion consists of zero or one non-explicit single-argument or non-explicit  call.

An expression is said to be implicitly convertible to  if and only if  can be  from, that is the declaration  is well-formed (can be compiled), for some invented temporary. Note that this is different from, where explicit constructors and conversion functions would additionally be considered.

Contextual conversions
In the following contexts, a context-specific type is expected, and the expression  of class type  is only allowed if

Such expression is said to be contextually implicitly converted to the specified type.
 * the argument of the ( is any object pointer type);
 * , where a literal class is used ( is any integral or unscoped enumeration type, the selected user-defined conversion function must be );
 * the controlling expression of the statement ( is any integral or enumeration type).

Value transformations
Value transformations are conversions that change the of an expression. They take place whenever an expression appears as an operand of an operator that expects an expression of a different value category.

Lvalue-to-rvalue conversion
of any non-function, non-array type can be implicitly converted to :
 * If is not a class type, the type of the  is the cv-unqualified version of.
 * Otherwise, the type of the is.

If an lvalue-to-rvalue conversion from an is required by a program, that program is ill-formed.

This conversion models the act of reading a value from a memory location into a CPU register.

Array-to-pointer conversion
An or  of type "array of  " or "array of unknown bound of " can be implicitly converted to a  of type "pointer to ". The resulting pointer refers to the first element of the array (see for details).

{{rrev|since=c++17|

Temporary materialization
A of any complete type  can be converted to an xvalue of the same type. This conversion initializes a of type T from the prvalue by evaluating the prvalue with the temporary object as its result object, and produces an xvalue denoting the temporary object. If is a class or array of class type, it must have an accessible and non-deleted destructor.

Temporary materialization occurs in the following situations:
 * when to a prvalue;
 * when performing a on a class prvalue;
 * when performing an array-to-pointer conversion (see above) or on an array prvalue;
 * when initializing an object of type std from a ;
 * when is applied to a prvalue (this is part of an unevaluated expression);
 * when is applied to a prvalue (this is part of an unevaluated expression);
 * when a prvalue appears as a.

Note that temporary materialization does not occur when initializing an object from a prvalue of the same type (by or ): such object is initialized directly from the initializer. This ensures "guaranteed copy elision". }}

Function-to-pointer conversion
An of function type  can be implicitly converted to a. This does not apply to non-static member functions because lvalues that refer to non-static member functions do not exist.

Integral promotion
s of small integral types (such as ) may be converted to prvalues of larger integral types (such as ). In particular, do not accept types smaller than  as arguments, and integral promotions are automatically applied after lvalue-to-rvalue conversion, if applicable. This conversion always preserves the value.

The following implicit conversions are classified as integral promotions:
 * ,, , and  can be converted to  if their respective entire value range can be held by the type , or  otherwise;
 * can be converted to the first type from the following list able to hold their entire value range:


 * an unscoped type whose underlying type is not fixed can be converted to the first type from the following list able to hold their entire value range:


 * an unscoped enumeration type whose underlying type is fixed can be converted to its underlying type, and, if the underlying type is also subject to integral promotion, to the promoted underlying type. Conversion to the unpromoted underlying type is better for the purposes of ;
 * a type can be converted to  if it can represent entire value range of the bit-field, otherwise to  if it can represent entire value range of the bit-field, otherwise no integral promotions apply;
 * the type can be converted to  with the value  becoming  and  becoming.

Note that all other conversions are not promotions; for example, chooses  ->  (promotion) over  ->  (conversion).

Floating-point promotion
A of type  can be converted to a prvalue of type. The value does not change.

Numeric conversions
Unlike the promotions, numeric conversions may change the values, with potential loss of precision.

Integral conversions
A of an integer type or of an unscoped enumeration type can be converted to any other integer type. If the conversion is listed under integral promotions, it is a promotion and not a conversion.
 * If the destination type is unsigned, the resulting value is the smallest unsigned value equal to the source value modulo $2n$ where $n$ is the number of bits used to represent the destination type.
 * That is, depending on whether the destination type is wider or narrower, signed integers are sign-extended or truncated and unsigned integers are zero-extended or truncated respectively.
 * If the destination type is signed, the value does not change if the source integer can be represented in the destination type. Otherwise the result is . (Note that this is different from, which is undefined).
 * If the source type is, the value is converted to zero and the value  is converted to the value one of the destination type (note that if the destination type is , this is an integer promotion, not an integer conversion).
 * If the destination type is, this is a boolean conversion (see below).

Floating-point conversions
If the conversion is listed under floating-point promotions, it is a promotion and not a conversion.
 * If the source value can be represented exactly in the destination type, it does not change.
 * If the source value is between two representable values of the destination type, the result is one of those two values (it is implementation-defined which one, although if IEEE arithmetic is supported, rounding defaults to nearest).
 * Otherwise, the behavior is undefined.

Floating–integral conversions

 * A of floating-point type can be converted to a prvalue of any integer type. The fractional part is truncated, that is, the fractional part is discarded. If the value cannot fit into the destination type, the behavior is undefined (even when the destination type is unsigned, modulo arithmetic does not apply). If the destination type is, this is a boolean conversion (see below).
 * A prvalue of integer or unscoped enumeration type can be converted to a prvalue of any floating-point type. The result is exact if possible. If the value can fit into the destination type but cannot be represented exactly, it is implementation defined whether the closest higher or the closest lower representable value will be selected, although if IEEE arithmetic is supported, rounding defaults to nearest. If the value cannot fit into the destination type, the behavior is undefined. If the source type is, the value is converted to zero, and the value  is converted to one.

Pointer conversions

 * A null pointer constant (see null), can be converted to any pointer type, and the result is the null pointer value of that type. Such conversion (known as null pointer conversion) is allowed to convert to a cv-qualified type as a single conversion, that is, it's not considered a combination of numeric and qualifying conversions.
 * A pointer to any (optionally cv-qualified) object type  can be converted to a prvalue pointer to (identically cv-qualified) . The resulting pointer represents the same location in memory as the original pointer value. If the original pointer is a null pointer value, the result is a null pointer value of the destination type.
 * A prvalue pointer to a (optionally cv-qualified) derived complete class type can be converted to a prvalue pointer to its (identically cv-qualified) base class. If the base class is inaccessible or ambiguous, the conversion is ill-formed  (won't compile). The result of the conversion is a pointer to the base class subobject within the pointed-to object. The null pointer value is converted to the null pointer value of the destination type.

Pointer-to-member conversions

 * A null pointer constant (see null) can be converted to any pointer-to-member type, and the result is the null member pointer value of that type. Such conversion (known as null member pointer conversion) is allowed to convert to a cv-qualified type as a single conversion, that is, it's not considered a combination of numeric and qualifying conversions.
 * A pointer to member of some type  in a base class  can be converted to a  pointer to member of the same type  in its derived complete class . If  is inaccessible, ambiguous, or virtual base of  or is a base of some intermediate virtual base of, the conversion is ill-formed (won't compile). The resulting pointer can be dereferenced with a  object, and it will access the member within the  base subobject of that  object. The null pointer value is converted to the null pointer value of the destination type.

Boolean conversions
A of integral, floating-point, unscoped enumeration, pointer, and pointer-to-member types can be converted to a prvalue of type.

The value zero (for integral, floating-point, and unscoped enumeration) and the null pointer and the null pointer-to-member values become. All other values become.

Qualification conversions

 * A of type pointer to  type  can be converted to a prvalue pointer to a more cv-qualified same type  (in other words, constness and volatility can be added).
 * A prvalue of type pointer to member of cv-qualified type in class  can be converted to a prvalue pointer to member of more cv-qualified type  in class.

"More" cv-qualified means that
 * a pointer to unqualified type can be converted to a pointer to ;
 * a pointer to unqualified type can be converted to a pointer to ;
 * a pointer to unqualified type can be converted to a pointer to ;
 * a pointer to type can be converted to a pointer to ;
 * a pointer to type can be converted to a pointer to.

For multi-level pointers, the following restrictions apply: a multilevel pointer which is $2n$-qualified pointer to $n$-qualified pointer to ... $cv1 0$-qualified pointer to $cv1 1$-qualified  is convertible to a multilevel pointer  which is $cv1 n-1$-qualified pointer to $cv1 n$-qualified pointer to ... $cv2 0$-qualified pointer to $cv2 1$-qualified only if
 * the number of levels is the same for both pointers;


 * if there is a in the $cv2 n-1$ qualification at some level (other than level zero) of, there is a  in the same level $cv2 n$ of ;
 * if there is a in the $cv1 k$ qualification at some level (other than level zero) of, there is a  in the same $cv2 k$ level of ;


 * if at some level the  is more cv-qualified than, then there must be a  at every single level (other than level zero) of  up until k: $cv1 k$.
 * same rules apply to multi-level pointers to members and multi-level mixed pointers to objects and pointers to members;
 * same rules apply to multi-level pointers that include pointers to array of known or unknown bound at any level (arrays of cv-qualified elements are considered to be identically cv-qualified themselves);
 * level zero is addressed by the rules for non-multilevel qualification conversions.

Note that in the C programming language, const/volatile can be added to the first level only:

{{rrev|since=c++17|

Function pointer conversions

 * A of type pointer to non-throwing function can be converted to a prvalue pointer to potentially-throwing function.
 * A prvalue of type pointer to non-throwing member function can be converted to a prvalue pointer to potentially-throwing member function.

}}

The safe bool problem
Until the introduction of explicit conversion functions in C++11, designing a class that should be usable in boolean contexts (e.g. ) presented a problem: given a user-defined conversion function, such as, the implicit conversion sequence allowed one additional standard conversion sequence after that function call, which means the resultant could be converted to , allowing such code as  or.

One early solution for this can be seen in std, which initially defines, so that the code such as compiles because  is convertible to , but  does not compile because  is not convertible to. This still allows nonsense code such as to compile.

Many pre-C++11 third party libraries were designed with a more elaborate solution, known as the Safe Bool idiom. std also allowed this idiom via, and was replaced (see here).