This commit is contained in:
2025-10-25 03:02:53 +03:00
commit 043225d523
3416 changed files with 681196 additions and 0 deletions

131
cppdraft/expr/cast.md Normal file
View File

@@ -0,0 +1,131 @@
[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.3Explicit 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.1General[dcl.decl.general]")*s* are discarded when determining the type of the
resulting prvalue; see [[expr.prop]](expr.prop "7.2Properties 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.4Explicit 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.3Explicit type conversion (cast notation)[expr.cast]")
[*unary-expression*](expr.unary.general#nt:unary-expression "7.6.2.1General[expr.unary.general]")
( [*type-id*](dcl.name#nt:type-id "9.3.2Type names[dcl.name]") ) [*cast-expression*](#nt:cast-expression "7.6.3Explicit 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.8Conversions")) 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.11Const cast")),
- [(4.2)](#4.2)
a static_cast ([[expr.static.cast]](expr.static.cast "7.6.1.9Static 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.10Reinterpret 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*]