78 C++完美转发

完美转发

在函数模板中,可以将参数“完美”的转发给其它函数。所谓完美,即不仅能准确的转发参数的值,还能保证被转发参数的左、右值属性不变。

C++11标准引入了右值引用和移动语义,所以,能否实现完美转发,决定了该参数在传递过程使用的是拷贝语义还是移动语义。

为了支持完美转发,C++11提供了以下方案:

1)如果模板中(包括类模板和函数模板)函数的参数书写成为T&& 参数名,那么,函数既可以接受左值引用,又可以接受右值引用。

2)提供了模板函数std::forward(参数) ,用于转发参数,如果 参数是一个右值,转发之后仍是右值引用;如果参数是一个左值,转发之后仍是左值引用。

注意

参数书写成为T&& 参数名

但并不是说它是右值引用,类似int&&这才是右值引用

#include <iostream>
using namespace std;
//完美转发
void func1(int &i)
{
    cout << "参数是左值=" << i << endl;
}
void func1(int &&i)
{
    cout << "参数是右值=" << i << endl;
}
void func2(int i)
{
    func1(i);
}
void func3(int &&i)
{
    func1(i);
}
void func3(int &i)
{
    func1(i);
}

void func4(int &&i)
{
    func1(move(i));
}
void func4(int &i)
{
    func1(i);
}

template <typename T>
void func5(T &&i)
{
    func1(move(i));
}
template <typename T>
void func5(T &i)
{
    func1(i);
}

template <typename T>
void func6(T &&i)
{
    func1(forward<T>(i));
}

void func7(int &&i)
{
    func1(forward<int>(i));
}

void test()
{
    int i = 3;
    func1(i);
    func1(33);
    /* 参数是左值=3
    参数是右值=33  */
    //上面代码调用,不会出现问题,但是如果不是字节调用,中间由其它函数中专,那中专的函数该怎么写呢?

    func2(i);
    func2(33);
    /* 参数是左值=3
参数是左值=33 */
    //上面代码输出结果可以看出,不是我们想要的,我们想要的是:func2()把参数传给func1()的时候,也要有左值和右值之分
    //如果参数在传递的过程中不能保持左/右值的属性,那就不能实现移动语义了.
    func3(i);
    func3(33);
    /*参数是左值=3
参数是左值=33  */
    //上面代码也不是我们想要的

    func4(i);
    func4(33);
    /*参数是左值=3
参数是右值=33 */
    //上面代码是我们想要的,但是该方法不是最好的,类似的还有下面的,改成两个模板

    func5(i);
    func5(33);
    /*参数是左值=3
参数是右值=33 */
    cout << "------------------" << endl;
    //使用最佳,C++11提供完美语义
    func6(i);
    func6(33);
}
int main()
{
    test();
    return 0;
}
参数是左值=3
参数是右值=33
参数是左值=3
参数是左值=33
参数是左值=3
参数是左值=33
参数是左值=3
参数是右值=33
参数是左值=3
参数是右值=33
------------------
参数是左值=3
参数是右值=33

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值