您的位置:首页 > 编程语言 > C语言/C++

C++类型操作

2016-05-16 00:08 330 查看
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);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: