static_cast 转换

来自cppreference.com
< cpp‎ | language
 
 
 
表达式
概述
值类别(左值 lvalue、右值 rvalue、亡值 xvalue)
求值顺序(序列点)
常量表达式
不求值表达式
初等表达式
lambda 表达式(C++11)
字面量
整数字面量
浮点字面量
布尔字面量
字符字面量,包含转义序列
字符串字面量
空指针字面量(C++11)
用户定义字面量(C++11)
运算符
赋值运算符a=ba+=ba-=ba*=ba/=ba%=ba&=ba|=ba^=ba<<=ba>>=b
自增与自减++a--aa++a--
算术运算符+a-aa+ba-ba*ba/ba%b~aa&ba|ba^ba<<ba>>b
逻辑运算符a||ba&&b!a
比较运算符a==ba!=ba<ba>ba<=ba>=b
成员访问运算符a[b]*a&aa->ba.ba->*ba.*b
其他运算符a(...)a,ba?b:c
运算符的替代表示形式
优先级和结合性
折叠表达式(C++17)
new 表达式
delete 表达式
throw 表达式
alignof
sizeof
sizeof...(C++11)
typeid
noexcept(C++11)
运算符重载
类型转换
隐式转换
const_cast
static_cast
reinterpret_cast
dynamic_cast
显式转换 (T)aT(a)
用户定义转换
 

用隐式和用户定义转换的组合在类型间转换。

目录

[编辑] 语法

static_cast < new_type > ( expression )

返回 new_type 类型的值。

[编辑] 解释

唯有下列转换能用 static_cast 执行,除了这种转换会转型走常性易变性的情况。

1) 若有从 expressionnew_type隐式转换序列,或若new_type 类型对象或引用的自 expression直接初始化会找到至少一个可生成函数,则 static_cast<new_type>(expression) 返回如同以 new_type Temp(expression); 初始化的虚构变量 Temp ,它可能涉及隐式转换、对 new_type 构造函数的调用或对用户定义转换运算符的调用。对于非引用的 new_type , static_cast 纯右值表达式的结果对象是被直接初始化者 (C++17 起)
2)new_type 是到某类类型 D 的指针或引用,且 expression 的类型是到其非虚基类 B 的指针或引用,则 static_cast 进行向下转型。若 BD 的歧义、不可访问或虚基类(或虚基类的基类),则此向下转型病态。这种 static_cast 不进行运行时检查以确保该对象的运行时类型确实是 D ,而且仅若此前提条件为其他方法所保证才能安全使用,例如在实现静多态时。安全的向下转型可以用 dynamic_cast 执行。
3)new_type 是右值引用类型,则 static_cast 转换泛左值、类纯右值或数组纯右值 (C++17 前)任何左值 (C++17 起) expression 的值为与该表达式指代相同对象,或指代其基类子对象(取决于 new_type )的亡值。若目标类型是表达式的不可访问或有歧义基类,则程序为病态。若表达式是位域左值,则它首先被转换成底层类型的纯右值。此类型的 static_cast 用于在 std::move 中实现移动语义。
(C++11 起)
4)new_typevoid 类型(可为 cv 限定),则 static_cast 在求值 expression 后舍弃其值。
5) 若存在从 new_typeexpression 类型的标准转换序列,且它不包含左值到右值、数组到指针、函数到指针、空指针、空成员指针、函数指针 (C++17 起)或布尔转换,则 static_cast 能进行该隐式转换的逆转换。
6) 若从 expressionnew_type 设计左值到右值、数组到指针或函数到指针转换,则它能显式以 static_cast 进行。
7) 有作用域枚举类型能转换成整数或浮点类型。当目标类型是 cv bool 时,若原值为零则结果为 false ,而对所有其他值结果为 true 。对于其余整数类型,若它们表示为目标类型,则结果是枚举的值,否则结果未指定。(C++11 起)
8) 整数、浮点或枚举类型能转换成任何完整枚举类型。若 expression 的值转换到枚举的底层类型后在范围(若底层类型固定,则范围是该类型的范围。若底层类型不固定,则范围是足以保有目标枚举所有枚举项的最小位域的所有可能值)外,则结果未指定 (C++17 前)是未定义行为 (C++17 起)
9) 指向某类 D 成员的指针能向上转型为指向其无歧义、可访问的基类 B 。此 static_cast 不进行检查以确保成员实际存在于所指向对象的运行时类型。
10) 指向 void (可为 cv 限定)指针纯右值可转换为指向任何类型的指针。若原指针值满足目标类型的对齐要求,则结果指针值不变,否则它未指定。转换任何指针到指向 void 指针并转换回指向原类型(或更加 cv 限定的)指针保持其原值。

同所有转型表达式,结果是:

  • 左值,若 new_type 是左值引用或到函数类型的右值引用;
  • 亡值,若 new_type 是到对象类型的右值引用;
  • 否则为纯右值。

[编辑] 注意

static_cast 亦可用于消歧义函数重载,通过进行到指定类型的函数到指针转换,如于 std::transform(s.begin(), s.end(), s.begin(), static_cast<int(*)(int)>(std::toupper));

[编辑] 关键词

static_cast

[编辑] 示例

#include <vector>
#include <iostream>
 
struct B {
    int m = 0;
    void hello() const {
        std::cout << "Hello world, this is B!\n";
    }
};
struct D : B {
    void hello() const {
        std::cout << "Hello world, this is D!\n";
    }
};
 
enum class E { ONE = 1, TWO, THREE };
enum EU { ONE = 1, TWO, THREE };
 
int main()
{
    // 1: 初始化转换
    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: 静态向下转型
    D d;
    B& br = d; // 通过隐式转换向上转型
    br.hello();
    D& another_d = static_cast<D&>(br); // 向下转型
    another_d.hello();
 
    // 3: 左值到亡值
    std::vector<int> v2 = static_cast<std::vector<int>&&>(v);
    std::cout << "after move, v.size() = " << v.size() << '\n';
 
    // 4: 弃值表达式
    static_cast<void>(v2.size());
 
    // 5. 隐式转换的逆
    void* nv = &n;
    int* ni = static_cast<int*>(nv);
    std::cout << "*ni = " << *ni << '\n';
 
    // 6. 数组到指针后随向上转型
    D a[10];
    B* dp = static_cast<B*>(a);
 
    // 7. 有作用域枚举到 int 或 float
    E e = E::ONE;
    int one = static_cast<int>(e);
    std::cout << one << '\n';
 
    // 8. int 到枚举,枚举到另一枚举
    E e2 = static_cast<E>(one);
    EU eu = static_cast<EU>(e2);
 
    // 9. 指向成员指针向上转型
    int D::*pm = &D::m;
    std::cout << br.*static_cast<int B::*>(pm) << '\n';
 
    // 10. void* 到任何类型
    void* voidp = &e;
    std::vector<int>* p = static_cast<std::vector<int>*>(voidp);
}

输出:

n = 3
v.size() = 10
Hello world, this is B!
Hello world, this is D!
after move, v.size() = 0
*ni = 3
1
0

[编辑] 参阅