[expr.cast] # 7 Expressions [[expr]](./#expr) ## 7.6 Compound expressions [[expr.compound]](expr.compound#expr.cast) ### 7.6.3 Explicit type conversion (cast notation) [expr.cast] [1](#1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L6850) The result of the expression (T) [*cast-expression*](#nt:cast-expression "7.6.3 Explicit type conversion (cast notation) [expr.cast]") is of type T[.](#1.sentence-1) The result is an lvalue if T is an lvalue reference type or an rvalue reference to function type and an xvalue if T is an rvalue reference to object type; otherwise the result is a prvalue[.](#1.sentence-2) [*Note [1](#note-1)*: If T is a non-class type that is cv-qualified, the[*cv-qualifier*](dcl.decl.general#nt:cv-qualifier "9.3.1 General [dcl.decl.general]")*s* are discarded when determining the type of the resulting prvalue; see [[expr.prop]](expr.prop "7.2 Properties of expressions")[.](#1.sentence-3) — *end note*] [2](#2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L6861) An explicit type conversion can be expressed using functional notation ([[expr.type.conv]](expr.type.conv "7.6.1.4 Explicit type conversion (functional notation)")), a type conversion operator (dynamic_cast, static_cast, reinterpret_cast,const_cast), or the [*cast*](#def:cast) notation[.](#2.sentence-1) [cast-expression:](#nt:cast-expression "7.6.3 Explicit type conversion (cast notation) [expr.cast]") [*unary-expression*](expr.unary.general#nt:unary-expression "7.6.2.1 General [expr.unary.general]") ( [*type-id*](dcl.name#nt:type-id "9.3.2 Type names [dcl.name]") ) [*cast-expression*](#nt:cast-expression "7.6.3 Explicit type conversion (cast notation) [expr.cast]") [3](#3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L6873) Any type conversion not mentioned below and not explicitly defined by the user ([[class.conv]](class.conv "11.4.8 Conversions")) is ill-formed[.](#3.sentence-1) [4](#4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L6877) The conversions performed by - [(4.1)](#4.1) a const_cast ([[expr.const.cast]](expr.const.cast "7.6.1.11 Const cast")), - [(4.2)](#4.2) a static_cast ([[expr.static.cast]](expr.static.cast "7.6.1.9 Static cast")), - [(4.3)](#4.3) a static_cast followed by a const_cast, - [(4.4)](#4.4) a reinterpret_cast ([[expr.reinterpret.cast]](expr.reinterpret.cast "7.6.1.10 Reinterpret cast")), or - [(4.5)](#4.5) a reinterpret_cast followed by a const_cast, can be performed using the cast notation of explicit type conversion[.](#4.sentence-1) The same semantic restrictions and behaviors apply, with the exception that in performing a static_cast in the following situations the conversion is valid even if the base class is inaccessible: - [(4.6)](#4.6) a pointer to an object of derived class type or an lvalue or rvalue of derived class type may be explicitly converted to a pointer or reference to an unambiguous base class type, respectively; - [(4.7)](#4.7) a pointer to member of derived class type may be explicitly converted to a pointer to member of an unambiguous non-virtual base class type; - [(4.8)](#4.8) a pointer to an object of an unambiguous non-virtual base class type, a glvalue of an unambiguous non-virtual base class type, or a pointer to member of an unambiguous non-virtual base class type may be explicitly converted to a pointer, a reference, or a pointer to member of a derived class type, respectively[.](#4.sentence-2) If a conversion can be interpreted in more than one of the ways listed above, the interpretation that appears first in the list is used, even if a cast resulting from that interpretation is ill-formed[.](#4.sentence-3) If astatic_cast followed by a const_cast is used and the conversion can be interpreted in more than one way as such, the conversion is ill-formed[.](#4.sentence-4) [*Example [1](#example-1)*: struct A { };struct I1 : A { };struct I2 : A { };struct D : I1, I2 { }; A* foo( D* p ) {return (A*)( p ); // ill-formed static_cast interpretation}int*** ptr = 0;auto t = (int const*const*const*)ptr; // OK, const_cast interpretationstruct S {operator const int*(); operator volatile int*();};int *p = (int*)S(); // error: two possible interpretations using static_cast followed by const_cast — *end example*] [5](#5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L6937) The operand of a cast using the cast notation can be a prvalue of type “pointer to incomplete class type”[.](#5.sentence-1) The destination type of a cast using the cast notation can be “pointer to incomplete class type”[.](#5.sentence-2) If both the operand and destination types are class types and one or both are incomplete, it is unspecified whether the static_cast or thereinterpret_cast interpretation is used, even if there is an inheritance relationship between the two classes[.](#5.sentence-3) [*Note [2](#note-2)*: For example, if the classes were defined later in the translation unit, a multi-pass compiler could validly interpret a cast between pointers to the classes as if the class types were complete at the point of the cast[.](#5.sentence-4) — *end note*]