左右值引用与完美转发示例

一个 MD5 计算类(以下代码仅为示例,移除了大部分与主题无关的实现):

class MD5 {
public:
    MD5(ifstream& in); // 构造函数
    void calc(ifstream& in); // MD5 计算函数
    std::string md5(void); // 获取 MD5 值
};

MD5::MD5(ifstream& in){
    calc(in);
}

调用方式:

ifstream ifs("file.txt");
MD5 md5(ifs);
cout << md5.md5() << endl;

不可通过以下方式调用:

MD5 md5(ifstream("file.txt"));

因为 ifstream("file.txt") 是一个右值,无法传递给左值引用 ifstream&

解决方法之一是使用右值引用:

MD5(ifstream&& in){
    calc(in);
}

但这样会导致 MD5 md5(ifs); 无法调用,因为 ifs 是左值。

解决方法之二是使用完美转发:

template<typename T>
MD5(T&& in){
    calc(forward<T>(in));
}

template<typename T>
void calc(T&& in){
    // ...
}

这样既可以接受左值也可以接受右值,实现了完美转发。
值得注意的是,因为构造函数调用了 calc 函数,所以 calc 函数也需要使用完美转发。
否则 MD5 md5(ifstream("file.txt")); 会导致编译错误。
(在 calc 函数中,不需要关心 in 具体是左值还是右值,当作普通引用即可)
因为原本 calc 函数接受的是左值引用,无法接受右值。

补充

这里的实现不需要维持 ifstream 的生命周期,对于其他场景下,需要维持右值的生命周期,可以使用 std::move 来转移右值。此处不赘述。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值