C++11:forward及完美转发

简介

一个右值引用参数作为函数的形参,在函数内部再转发该参数的时候它已经变成一个左值了,并不是原来的类型。
比如:

template <typename T>
void forwardValue(T &&val)
{
    processValue(val); // 右值引用参数会变成左值
}

如果我们需要按照参数原来的类型转发到另一个函数,这种转发就被成为完美转发。
所谓完美转发,是指在函数模板中,完全依照模板的参数的类型(即保持参数的左值、右值特征),将参数传递给函数模板中调用的另一个函数。
C++11提供了一个函数用于解决这个问题,通过std::forward来实现,不管参数是T&&这种未定的引用还是明确的左值引用或者右值引用,它会按照参数原本的类型转发。

示例

using namespace std;

template<typename T>
void PrintT(int &t)
{
    cout << "lvalue" << endl;
}

template<typename T>
void PrintT(int &&t)
{
    cout << "rvalue" << endl;
}

template<typename T>
void TestForward(T && v)
{
    PrintT(v);
    PrintT(std::forward<int>(v));
    PrintT(std::move(v));
    cout << endl;
}


int main()
{
    TestForward(1);
    int x = 1;
    TestForward(x);
    TestForward(std::forward<int>(x));

    test();
    return 0;
}

结果:

lvalue
rvalue
rvalue

lvalue
rvalue
rvalue

lvalue
rvalue
rvalue

注意第三个示例测试代码:

TestForward(std::forward<int>(x));

经过std::forward<int>(x)后变成了右值。

forward的转换规则为:

  • 模板参数为引用类型T、T&&时,返回右值引用
  • 模板参数为引用类型T&时,返回左值引用

扩展

右值引用、完美转发再结合可变模板参数,可以写一个万能的函数包装器,带返回值的、不带返回值的、带参数的或者不带参数的都可以委托这个万能的函数包装器来实现参数的完美转发。

万能函数包装器:

template<typename Function,typename... Args>
inline auto FuncWrapper(Function && f,Args && ... args) -> decltype (f(std::forward<Args>(args)...))
{
    return f(std::forward<Args>(args)...);
}

测试:

void test0()
{
    cout << "void" << endl;
}

int test1()
{
    return 1;
}

int test2(int x)
{
    return x;
}

string test3(string s1,string s2)
{
    return s1+s2;
}

void test()
{
    FuncWrapper(test0);
    cout << FuncWrapper(test1) << endl;
    int a = 1;
    cout << FuncWrapper(test2,a) << endl;
    cout << FuncWrapper(test3,"aa","bb") << endl;
}

输出:

void
1
1
aabb

参考:《深入应用C++11》
https://blog.csdn.net/u012508160/article/details/79218936

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

luoyayun361

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值