132 lines
5.3 KiB
Markdown
132 lines
5.3 KiB
Markdown
[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*]
|