C++传递指针引用参数编译错误及const修饰规则相关问题问询
问题本质:你混淆了const修饰的对象位置
你遇到的所有编译问题核心都源于对const int*&这个类型的语义理解偏差,按照C++类型从右向左读的规则,const int*& in的含义是:in是一个左值引用,引用的对象是「指向const int的指针」。这里的const只修饰指针指向的int值,既没有修饰指针本身,也没有修饰引用。
如果要声明「指向const int的指针的const左值引用」,正确写法是const int* const& in,这种写法就可以直接传&a正常编译。
1、为什么第一段代码无法编译,和const int&传参表现不一致?
你对比的两个场景的参数类型规则完全不同:
- 你举的可正常运行的示例参数是
const int& in,这是const左值引用,C++标准明确规定const左值引用可以绑定到右值,隐式生成的临时对象生命周期会延长到引用的作用域结束,所以传字面量5(右值)可以正常运行。 - 你第一段代码的参数
const int*& in是非const左值引用,C++规则里非const左值引用本身就不允许绑定右值。你传入的&a是int*类型的临时右值,需要先隐式转换为const int*类型的临时右值,自然无法被非const左值引用绑定,所以报出你看到的编译错误。
你可以把参数修改为const int* const& in,就和const int&的规则完全一致,不需要修改调用逻辑就能编译通过。
2、为什么定义变量b必须加const修饰?
核心是类型匹配的要求:
- 你举的普通
int传const int&的示例中,int类型的左值可以直接绑定到const int&,属于C++允许的「底层const扩充」,原变量a本身是否加const不影响,引用本身会保证不会修改a的值,所以可以正常传参。 - 而你原代码的参数要求的是绑定
const int*类型的左值:
如果你直接定义int* b = &a,b的类型是int*,和参数要求的const int*不匹配,需要做隐式类型转换,转换出来的结果是临时右值,还是无法被非const左值引用绑定。
只有你显式定义const int* b = &a,b本身就是const int*类型的左值,类型完全匹配,不需要做隐式转换,才能正常绑定到参数的引用上。
补充:C++指针的const修饰位置规则
方便你后续区分:
const int* p/int const* p:const修饰指针指向的int,不能通过p修改指向的内容,p本身的指向可以修改int* const p:const修饰指针本身,p的指向不能修改,可以通过p修改指向的内容const int* const p:指针本身和指向的内容都不可修改
内容的提问来源于stack exchange,提问作者Dan
相关产品推荐
相关产品推荐

