Files
cppdraft_translate/cppdraft/expr/cast.md
2025-10-25 03:02:53 +03:00

132 lines
5.3 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[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*]