C++函数组合调用报错:候选函数要求第一个参数为左值
解决C++函数组合调用时的左值参数错误问题
问题场景
想要实现支持组合调用的函数doIt(doIt(x, y), z),但运行时触发错误:candidate function not viable: expects an l-value for 1st argument。
初始实现代码
auto doIt(std::list<std::map<int, std::any>>& x, std::list<std::map<int, std::any>>& y) { std::list<std::map<int, std::any>> z(x); return z; }
测试数据
std::list<std::map<int, std::any>> x = { {{0, 1}, {-1, 0.5f}}, {{0, 0}, {-1, 0.5f}} }; std::list<std::map<int, std::any>> y = { {{0, 1}, {1, 1}, {-1, 0.5f}}, {{0, 1}, {1, 0}, {-1, 0.5f}}, {{0, 0}, {1, 1}, {-1, 0.4f}}, {{0, 0}, {1, 0}, {-1, 0.6f}}, }; std::list<std::map<int, std::any>> z = { {{0, 1}, {1, 1}, {-1, 0.5f}}, {{0, 1}, {1, 0}, {-1, 0.8f}}, {{0, 0}, {1, 1}, {-1, 0.5f}}, {{0, 0}, {1, 0}, {-1, 0.6f}}, };
调用情况
- 分步调用无报错:
auto _t = doIt(x, y); _t = doIt(_t, y);
- 组合调用触发错误:
auto _t = doIt(doIt(x, y), z);
错误信息
input_line_23:2:2: error: no matching function for call to 'doIt' doIt(doIt(x, y), z) ^~~~ input_line_12:1:6: note: candidate function not viable: expects an l-value for 1st argument auto doIt(std::list>& x, std::list>& y) { ^
问题原因
初始函数的参数是非const左值引用,而doIt(x,y)返回的是临时对象(右值)。C++中,非const左值引用无法绑定右值,因此组合调用时,第一个参数是右值,不符合函数参数的类型要求;而分步调用时,_t是命名的左值,能正常绑定到非const左值引用,所以不会报错。
解决方案
将函数的参数改为const左值引用,const左值引用既可以绑定左值,也可以绑定右值,同时可以用类型别名简化冗长的类型书写:
using _item = std::list<std::map<int, std::any>>; auto doIt(const _item& x, const _item& y) { std::list<std::map<int, std::any>> z(x); return z; }
修改后即可正常支持doIt(doIt(x, y), z)这类组合调用。
内容的提问来源于stack exchange,提问作者Jane Wayne
相关产品推荐
相关产品推荐

