如何让同一函数同时接收左值与右值Stream引用?
解决方案:让
parse兼容左值和右值参数 你遇到的问题本质是:非const左值引用无法绑定临时右值对象——当前parse(Stream & in)只能接受可修改的左值(比如第二个例子里的file变量),但Stream::asFile返回的是临时Stream对象(右值),所以第一个调用会编译失败。
下面提供两种可行的解决方式:
方式1:重载左值引用和右值引用版本
直接为parse写两个重载函数,分别处理左值和右值:
// 处理左值:修改传入的原对象状态,对应第二个调用场景 void parse(Stream& in) { // 你的原有逻辑,比如修改in的pos等状态 in.setPos(in.getPos() + 10); } // 处理右值:接收临时对象,内部复用左值版本的逻辑 void parse(Stream&& in) { // 注意:右值引用变量本身是左值,所以这里会调用上面的左值版本 parse(in); }
这样两种调用方式都能正常工作:
- 传临时对象时,匹配右值引用重载;
- 传左值变量时,匹配左值引用重载,且
file的状态会被保留并可后续访问。
方式2:使用万能引用(完美转发)
如果允许parse成为模板函数,可以用万能引用(T&&)来同时兼容左值和右值,代码更简洁:
#include <utility> // 必须包含这个头文件以使用std::forward template<typename T> void parse(T&& in) { // 直接编写你的业务逻辑,比如修改in的状态 in.readSomeData(); in.updatePos(); // 如果需要把in转发给其他函数,用std::forward<T>(in)实现完美转发 // processStream(std::forward<T>(in)); }
万能引用会自动推导参数类型:
- 传入左值时,
T被推导为Stream&,最终T&&折叠为Stream&(左值引用); - 传入右值时,
T被推导为Stream,最终T&&是Stream&&(右值引用)。
这种方式同样能满足两种调用场景的需求,且无需写多个重载。
内容的提问来源于stack exchange,提问作者Anne Quinn
相关产品推荐
相关产品推荐

