C++类型操作

C++中,对类型进行操作的有 typedef,using,decltype。

decltype 不对表达式求值,这一点同sizeof 一样。所以如果表达式中包含函数调用,并不需要看到该函数的定义实现,只需看到声明即可。

struct Default {
    int foo() const {return 1;}
};
 
struct NonDefault {
    NonDefault(const NonDefault&) {}
    int foo() const {return 1;}
};
 
int main()
{
    decltype(Default().foo()) n1 = 1; // int n1
//  decltype(NonDefault().foo()) n2 = n1; // error: no default constructor
    decltype(std::declval<NonDefault>().foo()) n2 = n1; // int n2
    std::cout << "n2 = " << n2 << '\n';
}

这里 NonDefault() 都不存在,所以虽然不发生调用的过程,仍然会有编译错误。这种情况还有构造函数被标记为 = delete,一样相当于不存在。

declval<T>()  也可以写成 declval(T) ,等价的。

declval<T>() 的类型 为 类型T加上右值引用,这里存在引用折叠,只有当T是左值引用类型时,返回的是左值引用,其他情况,返回的都是右值引用类型。

C++中的引用语义使得引用变量总是代表其所绑定的对象,通过类型转换,可以将引用变量绑定到对象地址开始的部分内存上。即将对象转换为引用类型,相当于为对象绑定了一个引用变量。

c++中的变量名本来就对应着存储该对象的一块内存(包括数组名),而不是现代编程语言中的名称与对象分离。将对象转化为引用就是将对象的起始地址开始的内存绑定到引用上。

    int i = 0xeedd;
    char& ref = reinterpret_cast<char&>(i);
    ref = 0xff;
    printf("%x", i);

输出:eeff .   //这里是小端模式

需要说明的地方:C++11中存在左值和右值引用,对于上边的例子,reinterpret_cast<char&&>(i) 得到的是右值,reinterpret_cast<char&>(i)得到的却是左值,虽然得到的值都是匿名的对象。这也是为啥标准库中的 move() 函数其实进行的操作就是转换为右值引用。有名对象 ==》左值, 逆否命题: 右值==》匿名对象。补充的:匿名对象也可以是左值。

更细的值分类,可以看这里

        或者用指针的方式来表达绑定的过程:

    
    int i = 0xeedd;
    char& p = *(char*)&i;
    p = 0xcc;
    printf("%x", i);
  

或者用C语言的表达方式:

    char* ptr = (char*)&i;
    *ptr = 0xaa;
    printf("%x", i);







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值