Explicit type conversion

Converts between types using a combination of explicit and implicit conversions.

# Notes

Feature-test macro Value Std Feature __cpp_auto_cast 202110L (C++23) auto(x) and auto{x}

# Example

#include <cassert>
#include <iostream>
 
double f = 3.14;
unsigned int n1 = (unsigned int)f; // C-style cast
unsigned int n2 = unsigned(f);     // function-style cast
 
class C1;
class C2;
C2* foo(C1* p)
{
    return (C2*)p; // casts incomplete type to incomplete type
}
 
void cpp23_decay_copy_demo()
{
    auto inc_print = [](int& x, const int& y)
    {
        ++x;
        std::cout << "x:" << x << ", y:" << y << '\n';
    };
 
    int p{1};
    inc_print(p, p); // prints x:2 y:2, because param y here is an alias of p
    int q{1};
    inc_print(q, auto{q}); // prints x:2 y:1, auto{q} (C++23) casts to prvalue,
                           // so the param y is a copy of q (not an alias of q)
}
 
// 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
    assert(a == nullptr);
 
    cpp23_decay_copy_demo();
}

# Defect reports

DRApplied toBehavior as publishedCorrect behavior
CWG 1223(P2915R0)C++11the addition of trailing return type introduced more ambiguitiesresolves them
CWG 1893C++11function-style cast did not consider pack expansionsconsiders them
CWG 2351C++11void{} was ill-formedmade well-formed
CWG 2620C++98the resolution of ambiguous functionparameters might be misinterpretedimproved the wording
CWG 2828C++98a C-style cast was ill-formed if multiple interpretationsof a static_cast followed by a const_cast exist,regardless of whether these conversions are actually usedonly considers theconversionspossibly being used
CWG 2894C++98function-style casts could create reference rvaluescan only create reference lvalues

# See also