[conv] # 7 Expressions [[expr]](./#expr) ## 7.3 Standard conversions [conv] ### [7.3.1](#general) General [[conv.general]](conv.general) [1](#general-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L503) Standard conversions are implicit conversions with built-in meaning[.](#general-1.sentence-1) [conv] enumerates the full set of such conversions[.](#general-1.sentence-2) A[*standard conversion sequence*](#def:conversion_sequence,standard "7.3.1 General [conv.general]") is a sequence of standard conversions in the following order: - [(1.1)](#general-1.1) Zero or one conversion from the following set: lvalue-to-rvalue conversion, array-to-pointer conversion, and function-to-pointer conversion[.](#general-1.1.sentence-1) - [(1.2)](#general-1.2) Zero or one conversion from the following set: integral promotions, floating-point promotion, integral conversions, floating-point conversions, floating-integral conversions, pointer conversions, pointer-to-member conversions, and boolean conversions[.](#general-1.2.sentence-1) - [(1.3)](#general-1.3) Zero or one function pointer conversion[.](#general-1.3.sentence-1) - [(1.4)](#general-1.4) Zero or one qualification conversion[.](#general-1.4.sentence-1) [*Note [1](#general-note-1)*: A standard conversion sequence can be empty, i.e., it can consist of no conversions[.](#general-1.sentence-4) — *end note*] A standard conversion sequence will be applied to an expression if necessary to convert it to an expression having a required destination type and value category[.](#general-1.sentence-5) [2](#general-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L533) [*Note [2](#general-note-2)*: Expressions with a given type will be implicitly converted to other types in several contexts: - [(2.1)](#general-2.1) When used as operands of operators[.](#general-2.1.sentence-1) The operator's requirements for its operands dictate the destination type ([[expr.compound]](expr.compound "7.6 Compound expressions"))[.](#general-2.1.sentence-2) - [(2.2)](#general-2.2) When used in the condition of an if statement ([[stmt.if]](stmt.if "8.5.2 The if statement")) or iteration statement ([[stmt.iter]](stmt.iter "8.6 Iteration statements"))[.](#general-2.2.sentence-1) The destination type isbool[.](#general-2.2.sentence-2) - [(2.3)](#general-2.3) When used in the expression of a switch statement ([[stmt.switch]](stmt.switch "8.5.3 The switch statement"))[.](#general-2.3.sentence-1) The destination type is integral[.](#general-2.3.sentence-2) - [(2.4)](#general-2.4) When used as the source expression for an initialization (which includes use as an argument in a function call and use as the expression in a return statement)[.](#general-2.4.sentence-1) The type of the entity being initialized is (generally) the destination type[.](#general-2.4.sentence-2) See [[dcl.init]](dcl.init "9.5 Initializers"), [[dcl.init.ref]](dcl.init.ref "9.5.4 References")[.](#general-2.4.sentence-3) — *end note*] [3](#general-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L556) An expression E can be[*implicitly converted*](#def:conversion,implicit "7.3.1 General [conv.general]") to a type T if and only if the declaration T t = E; is well-formed, for some invented temporary variable t ([[dcl.init]](dcl.init "9.5 Initializers"))[.](#general-3.sentence-1) [4](#general-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L562) Certain language constructs require that an expression be converted to a Boolean value[.](#general-4.sentence-1) An expression E appearing in such a context is said to be[*contextually converted to bool*](#def:conversion,contextual_to_bool "7.3.1 General [conv.general]") and is well-formed if and only if the declaration bool t(E); is well-formed, for some invented temporary variable t ([[dcl.init]](dcl.init "9.5 Initializers"))[.](#general-4.sentence-2) [5](#general-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L569) Certain language constructs require conversion to a value having one of a specified set of types appropriate to the construct[.](#general-5.sentence-1) An expression E of class type C appearing in such a context is said to be[*contextually implicitly converted*](#def:contextually_implicitly_converted "7.3.1 General [conv.general]") to a specified type T and is well-formed if and only if E can be implicitly converted to a type T that is determined as follows:C is searched for non-explicit conversion functions whose return type is cv T or reference to cvT such that T is allowed by the context[.](#general-5.sentence-2) There shall be exactly one such T[.](#general-5.sentence-3) [6](#general-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L583) The effect of any implicit conversion is the same as performing the corresponding declaration and initialization and then using the temporary variable as the result of the conversion[.](#general-6.sentence-1) The result is an lvalue if T is an lvalue reference type or an rvalue reference to function type ([[dcl.ref]](dcl.ref "9.3.4.3 References")), an xvalue if T is an rvalue reference to object type, and a prvalue otherwise[.](#general-6.sentence-2) The expression E is used as a glvalue if and only if the initialization uses it as a glvalue[.](#general-6.sentence-3) [7](#general-7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L593) [*Note [3](#general-note-3)*: For class types, user-defined conversions are considered as well; see [[class.conv]](class.conv "11.4.8 Conversions")[.](#general-7.sentence-1) In general, an implicit conversion sequence ([[over.best.ics]](over.best.ics "12.2.4.2 Implicit conversion sequences")) consists of a standard conversion sequence followed by a user-defined conversion followed by another standard conversion sequence[.](#general-7.sentence-2) — *end note*] [8](#general-8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L602) [*Note [4](#general-note-4)*: There are some contexts where certain conversions are suppressed[.](#general-8.sentence-1) For example, the lvalue-to-rvalue conversion is not done on the operand of the unary & operator[.](#general-8.sentence-2) Specific exceptions are given in the descriptions of those operators and contexts[.](#general-8.sentence-3) — *end note*] ### [7.3.2](#lval) Lvalue-to-rvalue conversion [[conv.lval]](conv.lval) [1](#lval-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L612) A [glvalue](basic.lval#def:glvalue "7.2.1 Value category [basic.lval]") of a non-function, non-array type T can be converted to a prvalue[.](#lval-1.sentence-1)[43](#footnote-43 "For historical reasons, this conversion is called the “lvalue-to-rvalue” conversion, even though that name does not accurately reflect the taxonomy of expressions described in [basic.lval].") If T is an incomplete type, a program that necessitates this conversion is ill-formed[.](#lval-1.sentence-2) If T is a non-class type, the type of the prvalue is the cv-unqualified version of T[.](#lval-1.sentence-3) Otherwise, the type of the prvalue is T[.](#lval-1.sentence-4)[44](#footnote-44 "In C++ class and array prvalues can have cv-qualified types. This differs from C, in which non-lvalues never have cv-qualified types.") [2](#lval-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L634) When an lvalue-to-rvalue conversion is applied to an expression E, and either - [(2.1)](#lval-2.1) E is not potentially evaluated, or - [(2.2)](#lval-2.2) the evaluation of E results in the evaluation of a member Ex of the set of potential results of E, and Ex names a variable x that is not odr-used by Ex ([[basic.def.odr]](basic.def.odr "6.3 One-definition rule")), the value contained in the referenced object is not accessed[.](#lval-2.sentence-1) [*Example [1](#lval-example-1)*: struct S { int n; };auto f() { S x { 1 };constexpr S y { 2 };return [&](bool b) { return (b ? y : x).n; };}auto g = f();int m = g(false); // undefined behavior: access of x.n outside its lifetimeint n = g(true); // OK, does not access y.n — *end example*] [3](#lval-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L659) The result of the conversion is determined according to the following rules: - [(3.1)](#lval-3.1) If T is cv std​::​nullptr_t, the result is a null pointer constant ([[conv.ptr]](#ptr "7.3.12 Pointer conversions"))[.](#lval-3.1.sentence-1) [*Note [1](#lval-note-1)*: Since the conversion does not access the object to which the glvalue refers, there is no side effect even if T is volatile-qualified ([[intro.execution]](intro.execution "6.10.1 Sequential execution")), and the glvalue can refer to an inactive member of a union ([[class.union]](class.union "11.5 Unions"))[.](#lval-3.1.sentence-2) — *end note*] - [(3.2)](#lval-3.2) Otherwise, if T has a class type, the conversion copy-initializes the result object from the glvalue[.](#lval-3.2.sentence-1) - [(3.3)](#lval-3.3) Otherwise, if the object to which the glvalue refers contains an invalid pointer value ([[basic.compound]](basic.compound "6.9.4 Compound types")), the behavior isimplementation-defined[.](#lval-3.3.sentence-1) - [(3.4)](#lval-3.4) Otherwise, if the bits in the value representation of the object to which the glvalue refers are not valid for the object's type, the behavior is undefined[.](#lval-3.4.sentence-1) [*Example [2](#lval-example-2)*: bool f() {bool b = true; char c = 42; memcpy(&b, &c, 1); return b; // undefined behavior if 42 is not a valid value representation for bool} — *end example*] - [(3.5)](#lval-3.5) Otherwise, the object indicated by the glvalue is read ([[defns.access]](defns.access "3.1 access"))[.](#lval-3.5.sentence-1) Let V be the value contained in the object[.](#lval-3.5.sentence-2) If T is an integer type, the prvalue result is the value of type T congruent ([[basic.fundamental]](basic.fundamental "6.9.2 Fundamental types")) to V, andV otherwise[.](#lval-3.5.sentence-3) [4](#lval-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L702) [*Note [2](#lval-note-2)*: See also [[basic.lval]](basic.lval "7.2.1 Value category")[.](#lval-4.sentence-1) — *end note*] [43)](#footnote-43)[43)](#footnoteref-43) For historical reasons, this conversion is called the “lvalue-to-rvalue” conversion, even though that name does not accurately reflect the taxonomy of expressions described in [[basic.lval]](basic.lval "7.2.1 Value category")[.](#footnote-43.sentence-1) [44)](#footnote-44)[44)](#footnoteref-44) In C++ class and array prvalues can have cv-qualified types[.](#footnote-44.sentence-1) This differs from C, in which non-lvalues never have cv-qualified types[.](#footnote-44.sentence-2) ### [7.3.3](#array) Array-to-pointer conversion [[conv.array]](conv.array) [1](#array-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L709) An lvalue or rvalue of type “array of N T” or “array of unknown bound of T” can be converted to a prvalue of type “pointer to T”[.](#array-1.sentence-1) The temporary materialization conversion ([[conv.rval]](#rval "7.3.5 Temporary materialization conversion")) is applied[.](#array-1.sentence-2) The result is a pointer to the first element of the array[.](#array-1.sentence-3) ### [7.3.4](#func) Function-to-pointer conversion [[conv.func]](conv.func) [1](#func-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L721) An lvalue of function type T can be converted to a prvalue of type “pointer to T”[.](#func-1.sentence-1) The result is a pointer to the function[.](#func-1.sentence-2)[45](#footnote-45 "This conversion never applies to non-static member functions because an lvalue that refers to a non-static member function cannot be obtained.") [45)](#footnote-45)[45)](#footnoteref-45) This conversion never applies to non-static member functions because an lvalue that refers to a non-static member function cannot be obtained[.](#footnote-45.sentence-1) ### [7.3.5](#rval) Temporary materialization conversion [[conv.rval]](conv.rval) [1](#rval-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L734) A prvalue of type T can be converted to an xvalue of type T[.](#rval-1.sentence-1) This conversion initializes a temporary object ([[class.temporary]](class.temporary "6.8.7 Temporary objects")) 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[.](#rval-1.sentence-2) T shall be a complete type[.](#rval-1.sentence-3) [*Note [1](#rval-note-1)*: If T is a class type (or array thereof), it must have an accessible and non-deleted destructor; see [[class.dtor]](class.dtor "11.4.7 Destructors")[.](#rval-1.sentence-4) — *end note*] [*Example [1](#rval-example-1)*: struct X { int n; };int k = X().n; // OK, X() prvalue is converted to xvalue — *end example*] ### [7.3.6](#qual) Qualification conversions [[conv.qual]](conv.qual) [1](#qual-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L755) A [*qualification-decomposition*](#def:qualification-decomposition "7.3.6 Qualification conversions [conv.qual]") of a type T is a sequence ofcvi and Pi such that T is “cv0 P0 cv1 P1 ⋯ cvn−1 Pn−1 cvn U” for n ≥ 0, where each cvi is a set of cv-qualifiers ([[basic.type.qualifier]](basic.type.qualifier "6.9.5 CV-qualifiers")), and each Pi is “pointer to” ([[dcl.ptr]](dcl.ptr "9.3.4.2 Pointers")), “pointer to member of class Ci of type” ([[dcl.mptr]](dcl.mptr "9.3.4.4 Pointers to members")), “array of Ni”, or “array of unknown bound of” ([[dcl.array]](dcl.array "9.3.4.5 Arrays"))[.](#qual-1.sentence-1) If Pi designates an array, the cv-qualifiers cvi+1 on the element type are also taken as the cv-qualifiers cvi of the array[.](#qual-1.sentence-2) [*Example [1](#qual-example-1)*: The type denoted by the [*type-id*](dcl.name#nt:type-id "9.3.2 Type names [dcl.name]") const int ** has three qualification-decompositions, taking U as “int”, as “pointer to const int”, and as “pointer to pointer to const int”[.](#qual-1.sentence-3) — *end example*] [2](#qual-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L782) Two types T1 and T2 are [*similar*](#def:similar_types "7.3.6 Qualification conversions [conv.qual]") if they have qualification-decompositions with the same n such that corresponding Pi components are either the same or one is “array of Ni” and the other is “array of unknown bound of”, and the types denoted by U are the same[.](#qual-2.sentence-1) [3](#qual-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L790) The [*qualification-combined type*](#def:type,qualification-combined "7.3.6 Qualification conversions [conv.qual]") of two types T1 and T2 is the type T3 similar to T1 whose qualification-decomposition is such that: - [(3.1)](#qual-3.1) for every i>0, cv3i is the union ofcv1i and cv2i, - [(3.2)](#qual-3.2) if either P1i or P2i is “array of unknown bound of”,P3i is “array of unknown bound of”, otherwise it is P1i, and - [(3.3)](#qual-3.3) if the resulting cv3i is different from cv1i or cv2i, or the resulting P3i is different from P1i or P2i, then const is added to every cv3k for 0