学习C++完美转发,这篇就足够了

Posted 写代码的牛顿

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了学习C++完美转发,这篇就足够了相关的知识,希望对你有一定的参考价值。


在学习本章之前先要了解什么是左右值,和左右值引用。参考我上一篇文章,C++的完美转发就是函数模板在向其他函数传递参数时该如何保留参数左右值属性的问题。我们分2部份学习,分别是引用折叠和std::forward()库函数的使用。


C++引用折叠和完美转发


在C++模板函数中我们需要对类型进行推导,形参会出现形如T&& Param时并不一定是右值,绑定的类型不知的话可能是左值,也可能是右值。这时模板函数类型为T&&时,就会出现行如T&& &&的情况,或者模板函数类型为T&时,就会出现行如T&& &的情况,此时则需要进行引用折叠。现在我们定义几个Fun函数,打印一条消息,看引用折叠效果。代码示例如下:


void Fun(int& Value) { std::cout << "lvalue ref" << std::endl; }
void Fun(int&& Value) { std::cout << "rvalue ref" << std::endl; }
void Fun(const int& Value) { std::cout << "const lvalue ref" << std::endl; }
void Fun(const int&& Value) { std::cout << "const rvalue ref" << std::endl; }

template<typename T>
void PerfectForward(T&& Param)
{
    Fun(std::forward<T>(Param));
}


std::forward()模板函数只有在它的参数绑定到一个右值上的时候,才转换它的参数到一个右值。我们有一个通俗易懂的识别引用折叠后数据类型的方法:传入的参数const属性不会变化,右值和右值引用会被折叠为右值引用,左值和左值引用会被折叠为左值引用。也就是说左右值引用的属性也不会变化。

我们还是以实际代码作为例子,观察运行结果。


int N = 10; //左值
int& R = N; //左值引用,变量R时一个左值
int&& RR = 20; //右值引用,变量RR是一个左值
const int& CR = N; //const左值引用,变量CR是一个左值
const int&& CRR = 20; //const右值引用,变量CRR是一个左值

PerfectForward(1); //传入右值被折叠为右值引用,调用右值引用函数
PerfectForward(R); //传入左值被折叠为左值引用,调用左值引用函数
PerfectForward(std::move(N)); //传入右值,被折叠为右值,调用右值引用函数
PerfectForward(RR); //传入左值,被折叠为左值,调用左值引用函数
PerfectForward(CR); //传入左值,被折叠为左值,调用const左值引用函数
PerfectForward(std::move(CRR)); //传入右值,被折叠为右值,调用const右值引用函数


在这里再次强烈推荐上一篇文章,必须要搞懂,还要反复理解引用折叠后的数据类型识别方法,只要正确区分左右值这部分代码将会很容易看懂。


我们运行实际代码看看效果。



到此为止,我们已经把引用折叠和完美转发讲完。实际上的完美转发,只是C++的语法糖,1byte都不消耗。



往期推荐



以上是关于学习C++完美转发,这篇就足够了的主要内容,如果未能解决你的问题,请参考以下文章

Python文件操作,看这篇就足够

Nginx 性能优化有这篇就足够了!

Flink面试,看这篇就足够了

MySQL事务(transaction) (有这篇就足够了..)

C++中的万能引用和完美转发

JVM面试题,看这篇就足够了(87题详解)