C++ std::forward()

在线调试网站:

https://wandbox.org/

#include <iostream>       
#include <thread>         
#include <mutex>          
 
void func(int &&args) {
    std::cout << args << std::endl;
}

int main () {

    int a = 10;
    func(20);    
    func(a);     
    func(std::move(a));   
 
    return 0;
}

编译错误信息:需要的是右值,但是传入的是左值,类型不匹配;

prog.cc: In function 'int main()':
prog.cc:13:10: error: cannot bind rvalue reference of type 'int&&' to lvalue of type 'int'
   13 |     func(a);
      |          ^
prog.cc:5:17: note:   initializing argument 1 of 'void func(int&&)'
    5 | void func(int &&args) {
      |           ~~~~~~^~~~

#include <iostream>       
#include <thread>         
#include <mutex>          
 
void func(int &arg) {
    std::cout << "func lvalue:" << arg << std::endl;
}
void func(int &&arg) {
    std::cout << "func rvalue" << arg << std::endl;
}

template <typename T>
void wrapper(T &&args) {
    func(args);
}
int main() {
    int a = 10; 
    wrapper(a);
    wrapper(20);
    return 0;
}

最终都调用了func(int &arg)

func lvalue:10
func lvalue:20

虽然咱们调用wrapper()函数时,传入的参数一个是左值,一个是右值,可是最终的输出确都是左值。缘由是咱们在中间加了一层转发函数wrapper()。

引用叠加,引用是能够叠加的,对于 T &&a; 叠加规则以下:

(1)当T类型为 Type 时,a 为 Type &&a,右值引用。

(2)当T类型为 Type& 时,a为 Type &a,左值引用。(这点还在思考中)

(3)当T类型为 Type&& 时,a为 Type &&a,右值引用。

经过引用叠加,分析以上示例可知,调用wrapper()时,wrapper(a) 是调用的原型是 wrapper(int &),是左值调用;wrapper(20)调用的原型是wrapper(int &&),是右值调用。可是在wrapper()函数内部,不管如何,args都是一个左值,在调用func()函数的时候,调用的func()原型老是func(int &)。

所以,右值引用属性不能被转发。因此,C++11提供了std::forward()函数用于完美转发。即,在转发过程当中,左值引用在被转发以后仍然保持左值属性,右值引用在被转发以后依然保持右值属性。

#include <iostream>       
#include <thread>         
#include <mutex>          
 
void func(int &arg) {
    std::cout << "func lvalue:" << arg << std::endl;
}
void func(int &&arg) {
    std::cout << "func rvalue:" << arg << std::endl;
}

template <typename T>
void wrapper(T &&args) {
    //func(args);
    func(std::forward<T>(args));
}
int main() {
    int a = 10; 
    wrapper(a);
    wrapper(20);
    return 0;
}
func lvalue:10
func rvalue:20

思考:

1 完美转发解决了什么问题;

2 经典应用场景是什么;(锁,线程等需要move语义的场景)

  • 8
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值