C++完美转发

一、什么是完美转发

提到完美转发,就有必要说一下,什么是转发,什么样的转发才称得上是完美转发。

在C++中,转发指的就是函数之间的参数传递(例如函数f1接收了一个参数a,而后又将此参数a 传递给了其函数体内调用的另一个函数f2)

而完美转发指的就是在函数之间传递参数的过程中,参数在传递后的属性保持不变(如左值仍是左值,右值仍是右值,const修饰也会保留)。

二、常规转发存在的问题

对于普通的转发,参数在函数间传递时属性可能会发生改变,我们看一个例子。

#include <iostream>
#include <utility>

void an_orther_fun(int a, int& b)
{
   
    std::cout << "in an_orther_fun(): a = " << a << ", b = " << ++b << std::endl;
}

void transmit(int a, int b)
{
   
    an_orther_fun(a, b);
}

int main()
{
   
    int a = 2, b = 3;

    std::cout << " before transmit(): a = " << a << ", b = " << b << std::endl;
    
    transmit(a, b);
    
    std::cout << "  after transmit(): a = " << a << ", b = " << b << std::endl;
    
    return 0;
}

其输出为:

before transmit(): a = 2, b = 3
in an_orther_fun(): a = 2, b = 4
after transmit(): a = 2, b = 3

注意,函数an_orther_fun()的第二个参数类型是引用int&,并且我们在函数中给该引用的值加上了1(++b那里),也就是我们预期应当会修改其第二个参数的值加1。但根据输出,虽然我们在an_orther_fun()打印出了加1后的b的值。但在外层,我们执行tansmit()后,b的值并没有加 1。

这里的原因其实很显而易见的,就是我们b在从transmit()传递到an_other_fun()的时候,其属性已经改变了:transmit()中的b是外层b的一个副本,而不是引用。

这就是常规引用可能带来的转发问题。

你可能会说,我们将transmit()的第二个参数类型也改为引用int&不就可以解决了吗?

void transmit(int a, int& b) {
    ... }

在我们这个示例中,这样的修改确实是可以达成我们示例中的目的的。

但,这只是示例,实际还有更多的可能性。例如,如果上例中的b处是一个右值引用,怎么办?我们看下面的代码:

#include <iostream>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值