Explicit type conversion
Converts between types using a combination of explicit and implicit conversions.
Syntax
( new-type ) expression |
(1) | |
new-type ( expression ) |
(2) | |
new-type ( arg1, arg2, ... ) |
(3) | |
new-type ( ) |
(4) | |
new-type { arg1, arg2, ...(optional) } |
(5) | (since C++11) |
template-name ( arg1, arg2, ...(optional) ) |
(6) | (since C++17) |
template-name { arg1, arg2, ...(optional) } |
(7) | (since C++17) |
auto ( expression ) |
(8) | (since C++23) |
auto { expression } |
(9) | (since C++23) |
Returns a value of type new-type.
Explanation
1) When the
C-style cast expression is encountered, the compiler attempts to interpret it as the following cast expressions, in this order:
a)
const_cast<new-type>(expression)
;
b)
static_cast<new-type>(expression)
, with extensions: pointer or reference to a
derived class is additionally allowed to be cast to pointer or reference to unambiguous base class (and vice versa) even if the base class is
inaccessible (that is, this cast ignores the private inheritance specifier). Same applies to casting
pointer to member to pointer to member of unambiguous non-virtual base;
c)
static_cast
(with extensions) followed by
const_cast
;
d)
reinterpret_cast<new-type>(expression)
;
e)
reinterpret_cast
followed by
const_cast
.
The first choice that satisfies the requirements of the respective cast operator is selected, even if it cannot be compiled (see example). If the cast can be interpreted in more than one way as
static_cast
followed by a
const_cast
, it cannot be compiled.
In addition, C-style cast notation is allowed to cast from, to, and between pointers to incomplete class type. If both
expression and
new-type are pointers to incomplete class types, it's unspecified whether
static_cast
or
reinterpret_cast
gets selected.
2) The
functional cast expression consists of a simple type specifier or a typedef specifier (in other words, a single-word type name:
unsigned int(expression)
or
int*(expression)
are not valid), followed by a single expression in parentheses. This cast expression is exactly equivalent to the corresponding C-style cast expression.
3) If there are more than one expression
or braced-init-list (since C++11) in parentheses,
new-type must be a class with a suitably declared
constructor. This expression is a prvalue of type
new-type
designating a temporary (until C++17)
whose result object is (since C++17)
direct-initialized with
expression-list.
4) If
new-type names a non-array complete object type, this expression is an prvalue of type
new-type,
designating a temporary (until C++17)
whose result object is (possibly with added cv-qualifiers) (since C++17) of that type. If
new-type is an object type, the object is
value-initialized. If
new-type is (possibly
cv-qualified)
void
, the expression is a
void
prvalue
without a result object (since C++17).
5) A single-word type name followed by a
braced-init-list is a prvalue of the specified type
designating a temporary (until C++17)
whose result object is (since C++17)
direct-list-initialized with the specified
braced-init-list. If
new-type is (possibly
cv-qualified)
void
, the expression is a
void
prvalue
without a result object (since C++17).
This is the only cast expression that can create an array prvalue. (until C++20)
8,9) The
auto
specifier is replaced with the deduced type of the invented variable
x
declared with
auto x(expression);
(which is never interpreted as a function declaration) or
auto x{expression};
respectively. The result is always a prvalue of an object type.
As with all cast expressions, the result is:
|
(until C++11) |
|
(since C++11) |
Example
double f = 3.14; unsigned int n1 = (unsigned int)f; // C-style cast unsigned int n2 = unsigned(f); // functional cast class C1; class C2; C2* foo(C1* p) { return (C2*)p; // casts incomplete type to incomplete type } // In this example, C-style cast is interpreted as static_cast // even though it would work as reinterpret_cast struct A {}; struct I1 : A {}; struct I2 : A {}; struct D : I1, I2 {}; int main() { D* d = nullptr; // A* a = (A*)d; // compile-time error A* a = reinterpret_cast<A*>(d); // this compiles }
References
- C++20 standard (ISO/IEC 14882:2020):
- 7.6.1.4 Explicit type conversion (functional notation) [expr.type.conv]
- 7.6.3 Explicit type conversion (cast notation) [expr.cast]
- C++17 standard (ISO/IEC 14882:2017):
- 8.2.3 Explicit type conversion (functional notation) [expr.type.conv]
- 8.4 Explicit type conversion (cast notation) [expr.cast]
- C++14 standard (ISO/IEC 14882:2014):
- 5.2.3 Explicit type conversion (functional notation) [expr.type.conv]
- 5.4 Explicit type conversion (cast notation) [expr.cast]
- C++11 standard (ISO/IEC 14882:2011):
- 5.2.3 Explicit type conversion (functional notation) [expr.type.conv]
- 5.4 Explicit type conversion (cast notation) [expr.cast]
- C++03 standard (ISO/IEC 14882:2003):
- 5.2.3 Explicit type conversion (functional notation) [expr.type.conv]
- 5.4 Explicit type conversion (cast notation) [expr.cast]
- C++98 standard (ISO/IEC 14882:1998):
- 5.2.3 Explicit type conversion (functional notation) [expr.type.conv]
- 5.4 Explicit type conversion (cast notation) [expr.cast]
See also
const_cast conversion |
adds or removes const |
static_cast conversion |
performs basic conversions |
dynamic_cast conversion |
performs checked polymorphic conversions |
reinterpret_cast conversion |
performs general low-level conversions |
standard conversions | implicit conversions from one type to another |
C documentation for cast operator |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/language/explicit_cast