前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【C++11】 改成程序性能的方法--完美转发

【C++11】 改成程序性能的方法--完美转发

作者头像
CPP开发前沿
发布2021-11-16 13:48:18
2380
发布2021-11-16 13:48:18
举报
文章被收录于专栏:CPP开发前沿CPP开发前沿

所谓的完美转发,实际上就是指在C++函数模板中,完全按照函数模板的参数类型将参数传递给函数模板中调用的另外一个参数。通俗点解释就是,如果一个参数不管是右值引用还是左值引用,函数调用时都不会改变参数的类型。C++11给我们提供了这样一个函数std::forward,它就是专门为完美转发而生的,实际使用时它会完全按照参数本来的类型进行转发,而不是改变。

std::forward原型:

代码语言:javascript
复制
//左值引用版本
template <class T> 
T&& forward (typename remove_reference<T>::type& arg) noexcept;
//右值引用版本
template <class T> 
T&& forward (typename remove_reference<T>::type&& arg) noexcept;

在上面的声明中,主要包含两点:

1)如果参数是左值,函数不会修改参数类型,也将返回一个左值引用;

2)如果参数是右值,函数也将返回一个右值引用;

1 参数转发示例

代码语言:javascript
复制
// forward example
#include <utility>      // std::forward
#include <iostream>     // std::cout
void printValue(const int &t){
    std::cout<<"lValue="<<t<<std::endl;
}
void printValue(int&& t){
    std::cout<<"rValue="<<t<<std::endl;
}
template<typename T>
void testForward(T&& v){
   printValue(v);
   printValue(std::forward<T>(v));
   printValue(std::move(v));
}
int main () {
  testForward(1);
  int x=1;
  printValue(x);
  printValue(std::forward<int>(x));
  return 0;
}

程序运行结果为:

代码语言:javascript
复制
lValue=1
rValue=1
rValue=1
lValue=1
rValue=1

从运行结果可以看出:

1)在testForward函数中,函数参数为右值引用,当传入参数1时,因为1是右值,所以T&&v经过初始化后变成了右值引用。在该函数内部执行时,v先后从一个右值变成了左值,然后又变成了右值引用。

2)testForward(x)未定的类型T&&被一个左值初始化后变成了一个左值应用,后面经过完美转发后又保持了原有的数据类型,变成了右值引用。

从上面的实例可以知道,使用右值引用、完美转发、以及可变参数模板后,可以实现一个完成的函数宝装器,具体如下:

代码语言:javascript
复制
template<class Function,class ... Args>
inline auto FunctionWrapper(Function &&f,Args && ... args) -> decltype(f(std::forward<Args>(args)...))
{
    return f(std::forward<Args>(args)...);
}

代码如上,是不是很简单,这个函数已经完美实现一个万能的函数包装器,下面我们可以写一个代码进行验证。

代码语言:javascript
复制
void test0()
{
    std::cout<<"void"<<std::endl;
}

int test1()
{
    std::cout<<1<<std::endl;
    return 1;
}

int test2(int x)
{
    std::cout<<x<<std::endl;
    return x;
}

std::string test3(std::string str1,std::string str2)
{
     std::cout<<str2+str1<<std::endl;
    return str2+str1;
}

void test()
{
    FunctionWrapper(test0);
    FunctionWrapper(test1);
    FunctionWrapper(test2,2);
    FunctionWrapper(test3,"world","hello");
}
int main (
{
  test();
  return 0;
}

程序运行结果如下:

代码语言:javascript
复制
void
1
2
helloworld

- EOF -

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-09-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 CPP开发前沿 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档