C++构造函数参数从Base* const&改为Base*&后重载决议异常原因
重载决议差异原因及相关问题解答
核心差异根源
- 你传入的实参类型为
Child*,要匹配Base*相关的重载,首先需要执行派生类指针到基类指针的隐式转换,这个转换的输出是一个临时的Base*右值,不是可修改的左值。
第一种情况(参数为Base* const&)
C语法规则允许const修饰的左值引用绑定到右值,因此这个重载属于可行候选。
同时C的重载优先级规则中,「派生类指针到基类指针的转换」优先级高于「任意指针到void*的转换」,因此会优先选中Base* const&版本的构造函数,输出对应内容。
第二种情况(参数为Base*&)
非常量左值引用不允许绑定到右值(避免函数无意间修改临时对象的值,产生无意义的逻辑),因此这个重载会被直接排除出可行候选列表。
此时唯一的可行重载就是void*版本的构造函数(任意指针类型都支持隐式转换为void*),因此最终会调用void*版本。
你可以通过修改实参类型验证这个逻辑:如果传入Base*类型的左值,Base*&版本就可以被正常选中:
Base* base_ptr = new Child(1); Wrapper w(base_ptr); // 此时会调用Base*&版本的构造函数
Base* const&的作用说明
它的作用不只是兼容临时对象,还有两层明确的语义:
- 向调用者承诺函数内部不会修改传入的指针本身的指向(注意是指针本身存储的地址值,不是指针指向的对象的内容)
- 可以同时接受左值、右值类型的
Base*参数,扩大了重载的适用范围
内容的提问来源于stack exchange,提问作者ClassY
相关产品推荐
相关产品推荐

