C++中const位置对引用绑定的影响:为何第5行合法第4行报错?
int i = 0; int* lv1 = &(++i); //++i 是左值 //int* rv1 = &(i++); //i++ 是右值 const int* &rv1 = &i; int* const &rv2 = &i; int* &&rv3 = &i; const int &rv4 = 5; int const &rv5 = 5;
问题解答
从引用绑定规则和顶层/底层const的类型影响两方面就能理清这个差异:
为什么第4行 const int* &rv1 = &i; 报错?
&i的类型是int*,而且是个临时右值(取地址操作返回的是右值)。而rv1是const int*&——这是一个指向const int的指针的非const左值引用。
这里有两个核心冲突:
- 非const左值引用本身就不允许绑定右值临时对象;
- 即便
int*能隐式转成const int*(底层const的添加符合类型安全),转换后得到的依然是const int*类型的临时右值,还是没法绑定到const int*&这种非const左值引用上。
所以这行代码必然编译报错。
为什么第5行 int* const &rv2 = &i; 不报错?
rv2的类型是int* const &——这是一个指向int的const指针的左值引用(这里的const是顶层const,修饰的是指针本身)。
根据C++规则,绑定const类型对象的左值引用,可以绑定匹配类型的右值临时对象。&i是int*类型的临时右值,它能隐式转换为int* const(顶层const可直接添加,不破坏类型兼容性),转换后的临时int* const对象就能被int* const &成功绑定,因此不会报错。
补充:顶层const与底层const的概念(出自《C++ Primer》)
- 顶层const:表示变量本身是const,比如
int* const p里的const——指针p本身不能被修改,但它指向的int值可以更改; - 底层const:表示变量指向的值是const,比如
const int* p里的const——指针p本身可以修改,但它指向的int值不能被更改。
内容的提问来源于stack exchange,提问作者seoubi
相关产品推荐
相关产品推荐

