static_cast conversion

< cpp‎ | language
Revision as of 07:36, 26 December 2012 by Cubbi (Talk | contribs)

C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Function declaration
Lambda function declaration
inline specifier
Exception specifications (deprecated)
noexcept specifier (C++11)
decltype (C++11)
auto (C++11)
alignas (C++11)
Storage duration specifiers
Alternative representations
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Attributes (C++11)
typedef declaration
Type alias declaration (C++11)
Implicit conversions - Explicit conversions
static_cast - dynamic_cast
const_cast - reinterpret_cast
Memory allocation
Class-specific function properties
Special member functions

Converts between types using a combination of implicit and user-defined conversions.



static_cast < Template:sparam > ( Template:sparam )

Returns a value of type new_type.


Only the following conversions can be done with static_cast, except when such conversions would cast away constness or volatility.

1) If a temporary object of type Template:sparam can be declared and initialized with Template:sparam, as by new_type Temp(expression);, which may involve implicit conversions, a call to the constructor of Template:sparam or a call to a user-defined conversion operator, then static_cast<type>(expression) computes and returns the value of that temporary object.
2) If Template:sparam is a pointer or reference to some class D and the type of Template:sparam is a pointer or reference to its non-virtual base B, static_cast performs a downcast. Such static_cast makes no runtime checks to ensure that the object's runtime type is actually D, and may only be used safely if this precondition is guaranteed by other means, such as when implementing static polymorphism. Safe downcast may be done with dynamic_cast.
3) If Template:sparam is an rvalue reference type, static_cast converts the value of Template:sparam to xvalue. This type of static_cast is used to implement move semantics in std::move. (since C++11)
4) If Template:sparam is the type void (possibly cv-qualified), static_cast discards the value of Template:sparam after evaluating it.
5) If an implicit conversion sequence from Template:sparam to the type of Template:sparam exists, that does not include lvalue-to-rvalue, array-to-pointer, function-to-pointer, null pointer, null member pointer, or boolean conversion, then static_cast can perform the inverse of that implicit conversion.
6) If conversion of Template:sparam to Template:sparam involves lvalue-to-rvalue, array-to-pointer, or function-to-pointer conversion, it can be performed explicitly by static_cast.
7) Scoped enumeration type can be converted to an integer or floating-point type. (since C++11)
8) Integer, floating-point, or enumeration type can be converted to any enumeration type (the result is unspecified if the value of Template:sparam, converted to the enumeration's underlying type, is not one of the target enumeration values)
9) A pointer to member of some class D can be upcast to a pointer to member of its base class B. This static_cast makes no checks to ensure the member actually exists in the runtime type of the pointed-to object.
10) A prvalue of type pointer to void (possibly cv-qualified) can be converted to pointer to any type. Conversion of any pointer to pointer to void and back to pointer to the original (or more cv-qualified) type preserves its original value.

As with all cast expressions, the result is:

  • an lvalue if new_type is an lvalue reference type or an rvalue reference to function type;
  • an xvalue if new_type is an rvalue reference to object type;
  • a prvalue otherwise.


static_cast may also be used to disambiguate function overloads by performing a function-to-pointer conversion to specific type, as in std::transform(s.begin(), s.end(), s.begin(), static_cast<int(*)(int)>(std::toupper));




#include <vector>
#include <iostream>
struct B {};
struct D : B {};
enum class E { ONE, TWO, THREE };
enum EU { ONE, TWO, THREE };
int main()
    // 1: initializing conversion
    int n = static_cast<int>(3.14); 
    std::cout << "n = " << n << '\n';
    std::vector<int> v = static_cast<std::vector<int>>(10);
    std::cout << "v.size() = " << v.size() << '\n';
    // 2: static downcast
    D d;
    B& br = d; // upcast via implicit conversion
    D& another_d = static_cast<D&>(br); // downcast
    // 3: lvalue to xvalue
    std::vector<int> v2 = static_cast<std::vector<int>&&>(v);
    std::cout << "after move, v.size() = " << v.size() << '\n';
    // 4: discarded-value expression
    // 5. inverse of implicit conversion
    // todo
    // 6. array-to-pointer followed by upcast
    D a[10];
    B* dp = static_cast<B*>(a);
    // 7. scoped enum to int or float
    E e = E::ONE;
    int one = static_cast<int>(e);
    // 8. int to enum, enum to another enum
    E e2 = static_cast<E>(one);
    EU eu = static_cast<EU>(e2);
    // 9. pointer to member upcast
    // todo
    // 10. void* to any type
    void* voidp = &e;
    std::vector<int>* p = static_cast<std::vector<int>*>(voidp);


n = 3
v.size() = 10
after move, v.size() = 0

See also