非const引用可绑定const引用不可绑定的场景?函数替换与测试疑问
咱们先逐个解决你的两个问题:
问题一:有没有调用
f1的表达式,换成f2就没法运行? 答案是完全没有。道理很直白:
f1的参数是NonTrivialClass&——也就是非const的左值引用,它只能接可以被修改的左值,比如普通的非const对象、返回非const引用的函数结果。f2的参数是NonTrivialClass const&——const左值引用的兼容性要强得多:所有能传给f1的实参,它都能接;除此之外,它还能接const对象、临时生成的对象(比如NonTrivialClass{}这种右值)。
简单说,f2的参数接受范围是包含f1的,所以只要能调用f1的代码,换成f2肯定也能跑。反过来倒是有很多f2能跑的代码换成f1会报错,但你问的情况不存在。
问题二:为什么加了
const限定符会导致测试不通过? 这种情况真的有可能,我见过好几个类似的场景:
函数签名不匹配,导致链接失败
如果招聘方要求你写的是double approx(vector<Point>& pts),但你写成了带const的版本,这俩其实是完全不同的函数(const是函数签名的一部分)。测试程序里调用的是不带const的那个,链接的时候就会找不到对应的函数定义,直接报错。这是最容易踩的坑,很多人会忽略参数的const会改变函数签名。你的实现里调用了Point的非const方法
如果approx的逻辑里需要调用Point的某些非const成员函数,而你用了const&的pts,那pts里的每个Point都是const对象,调用非const方法就会编译失败。举个例子:// 假设Point有个非const的get_x方法(虽然设计不太合理,但确实有可能) double approx(vector<Point> const& pts) { double total = 0; for (auto& p : pts) { total += p.get_x(); // 这里会编译报错:p是const Point&,不能调用非const方法 } return total / pts.size(); }要是用非const版本的
pts,p就是普通的Point&,就能正常调用这些方法。测试程序依赖函数修改传入的pts
虽然布冯实验一般只需要读取点的坐标,不需要修改,但如果测试用例的逻辑默认approx会修改pts(比如给点打个已处理的标记),那你的const版本因为没法修改pts,就会导致测试断言失败。这种情况属于测试用例的设计问题,但确实会让你的代码通不过测试。
内容的提问来源于stack exchange,提问作者YSC
相关产品推荐
相关产品推荐

