为何指向const的指针右值引用无法绑定非const指针?
指针与基础类型的右值引用绑定差异解析
核心原因:隐式转换对值类别的影响不同
基础类型的数值转换(如double→int)会将左值转换为纯右值(临时对象),而指针的const资格转换(如int*→const int*)会保留左值属性,转换后仍是左值。这两种转换对值类别的不同影响,直接导致了右值引用绑定规则的差异。
逐个案例分析
Case 1(编译错误,符合预期)
int x = 10; int *pX = &x; const int* &ref = pX; //compiler error (expected)
pX是int*类型的左值,const int* &是指向const int的指针的左值引用。左值引用要求绑定的表达式类型完全匹配(或派生类到基类的左值引用),但int*到const int*的资格转换后仍是左值,类型不匹配且非const左值引用无法绑定临时对象,因此报错。
Case 2(正常编译,符合预期)
int x = 10; int *pX = &x; const int* const &ref = pX; //ok (expected)
const int* const &是指向const int的指针的const左值引用。const左值引用允许绑定右值(包括转换生成的临时对象),pX经资格转换生成const int*类型的临时纯右值,可被const左值引用正常绑定,因此编译通过。
Case 3(编译错误,解析)
int x = 10; int *pX = &x; const int* &&ref = pX; //compiler error (why?)
pX是int*左值,转换为const int*属于资格转换,转换后的表达式仍是左值(而非纯右值)。右值引用const int*&&仅能绑定右值,无法绑定左值,因此编译器报错。这是指针场景与基础类型的核心差异:资格转换不会改变值类别。
Case 4(正常编译,解析)
int x = 10; const int* &&ref = &x; //ok (why?)
&x是int*类型的纯右值(取地址表达式的结果为纯右值),经资格转换后变为const int*类型的纯右值,属于右值范畴。右值引用可正常绑定该纯右值,因此编译通过。
基础类型与指针场景的差异总结
- 基础类型:左值经数值转换后生成纯右值(临时对象),属于右值,可绑定到对应类型的右值引用。
- 指针类型:左值经资格转换后仍为左值,无法绑定到右值引用;只有初始表达式本身是右值(如
&x这类纯右值),转换后仍是右值,才能绑定到右值引用。
内容的提问来源于stack exchange,提问作者Manuel
相关产品推荐
相关产品推荐

