当前位置:网站首页>(p40-p41) transfer and forward perfect forwarding of move resources
(p40-p41) transfer and forward perfect forwarding of move resources
2022-06-12 08:09:00 【Ordinary people who like playing basketball】
1.move
stay C++11 Added right value reference , And you cannot initialize an R-value reference with an l-value , If you want to initialize an R-value reference with an l-value, you need to use std::move () function , send use std::move Method can convert an lvalue to an lvalue .( The lvalue can be 、 lvalue reference 、 Right value reference converted to right value (STL The source code returns a dead value T&&))
Using this function doesn't move anything , But it has the same mobile semantics as the mobile constructor , Transfer the state or ownership of an object from one object to another , It's just a transfer , No memory copy .
In terms of implementation ,std::move Basically equivalent to a type conversion :static_cast<T&&>(lvalue);, The function prototype is as follows :
template<class _Ty>
_NODISCARD constexpr remove_reference_t<_Ty>&& move(_Ty&& _Arg) _NOEXCEPT
{
// forward _Arg as movable
return (static_cast<remove_reference_t<_Ty>&&>(_Arg));
}
- eg:
class Test
{
public:
Test(){
}
......
}
int main()
{
Test t;
// Initializes an R-value reference with an l-value , So the grammar is wrong
Test && v1 = t; // error
// Use move() The function converts an lvalue to an lvalue , In this way, the right value reference can be initialized .
Test && v2 = move(t); // ok
return 0;
}
- eg: Suppose a temporary container is large , And you need to assign this container to another container , You can perform the following operations :
list<string> ls;
ls.push_back("hello");
ls.push_back("world");
......
list<string> ls1 = ls; // Need to copy , Low efficiency
list<string> ls2 = move(ls);
- explain :
If not used std::move, Copying costs a lot , Low performance . Use move There's almost no price , It's just a transfer of ownership of resources . If there is a large heap memory or dynamic array inside an object , Use move () It is very convenient to transfer the ownership of data .
in addition , You can also write corresponding mobile constructors for classes (T::T(T&& another)), And assignment functions with mobile semantics (T&& T::operator=(T&& rhs)), When constructing objects and assigning values, reuse resources as much as possible , Because they all receive an R-value reference parameter .
2.forward
The right value reference type is value independent , When an R-value reference is used as a formal parameter of a function parameter , When forwarding this parameter to other functions inside the function , It becomes an lvalue ( Lvalue references are better understood ?), It's not the original type .
If you need to forward the parameter to another function according to the original type , have access to C++11 Provided std::forward () function , The function realized by this function is called perfect forwarding .
- The function prototype
// The function prototype
template <class T> T&& forward (typename remove_reference<T>::type& t) noexcept;
template <class T> T&& forward (typename remove_reference<T>::type&& t) noexcept;
// After streamlining
std::forward<T>(t);
- usage :
When T When it is an lvalue reference type ,t Will be converted to T Left value of type
When T When it is not an lvalue reference type ,t Will be converted to T Right value of type
- eg:
#include <iostream>
using namespace std;
template<typename T>
void printValue(T& t)
{
cout << "l-value: " << t << endl;
}
template<typename T>
void printValue(T&& t)
{
cout << "r-value: " << t << endl;
}
template<typename T>
void testForward(T&& v)
{
printValue(v);
printValue(move(v));
printValue(forward<T>(v));
cout << endl;
}
int main()
{
/* testForward(520); The formal parameter of the function is of undetermined reference type T&&, The argument is an R-value , After initialization, it is deduced as an R-value reference printValue(v); Named right value v, The compiler will treat it as an lvalue , The argument is an lvalue ( To be exact, it is an lvalue reference ) printValue(move(v)); The named R-value compiler treats it as an l-value , adopt move And convert it to an R-value , The argument is an R-value printValue(forward<T>(v));forward The template parameter of is an R-value reference , Finally, we get an R-value , The argument is `` Right value ` */
testForward(520);
int num = 1314;
/* testForward(num); The formal parameter of the function is of undetermined reference type T&&, The argument is an lvalue , After initialization, it is deduced as an lvalue reference printValue(v); The argument is an lvalue ( To be exact, it is an lvalue reference ) printValue(move(v)); adopt move Convert the left value to the right value , The argument is an R-value printValue(forward<T>(v));forward The template parameter of is an lvalue reference , Finally, you get an lvalue reference , The argument is an lvalue */
testForward(num);
/* testForward(forward<int>(num));forward The template type of is int, You'll end up with an R-value , The formal parameter of the function is of undetermined reference type T&& An R-value reference type is obtained after being initialized by an R-value printValue(v); Named right value v, The compiler will treat it as an lvalue ( To be exact, it is an lvalue reference ), The argument is an lvalue printValue(move(v)); The named R-value compiler treats it as an l-value , adopt move And convert it to an R-value , The argument is an R-value printValue(forward<T>(v));forward The template parameter of is an R-value reference , Finally, we get an R-value , The argument is an R-value */
testForward(forward<int>(num));
/* testForward(forward<int&>(num));forward The template type of is int&, You end up with an lvalue , The formal parameter of the function is of undetermined reference type T&& After being initialized by an lvalue, you get an lvalue reference type printValue(v); The argument is an lvalue ( To be exact, it is an lvalue reference ) printValue(move(v)); adopt move Convert the left value to the right value , The argument is an R-value printValue(forward<T>(v));forward The template parameter of is an lvalue reference , Finally, you get an lvalue , The argument is an lvalue */
testForward(forward<int&>(num));
/* testForward(forward<int&&>(num));forward The template type of is int&&, You'll end up with an R-value , The formal parameter of the function is of undetermined reference type T&& An R-value reference type is obtained after being initialized by an R-value printValue(v); Named right value v, The compiler will treat it as an lvalue ( To be exact, it is an lvalue reference ), The argument is an lvalue printValue(move(v)); The named R-value compiler treats it as an l-value , adopt move And convert it to an R-value , The argument is an R-value printValue(forward<T>(v));forward The template parameter of is an R-value reference , Finally, we get an R-value , The argument is an R-value */
testForward(forward<int&&>(num));
return 0;
}
- test :

#include <iostream>
using namespace std;
template<typename T>
void printValue(T& t)
{
cout << "l-value: " << t << endl;
}
//&& Is a reference to an undefined type
template<typename T>
void printValue(T&& t)
{
cout << "r-value: " << t << endl;
}
//&& Is a reference to an undefined type
template<typename T>
void testForward(T && v)
{
printValue(v);
printValue(move(v));
printValue(forward<T>(v));
cout << endl;
}
int main()
{
testForward(520);
int num = 1314;
testForward(num);
testForward(forward<int>(num));
testForward(forward<int&>(num));
testForward(forward<int&&>(num));
return 0;
}
- Reference resources : Transfer and perfect forwarding
边栏推荐
- Leetcode notes: biweekly contest 70
- 智能制造的时代,企业如何进行数字化转型
- 数据库基础——规范化、关系模式
- (p36-p39) right value and right value reference, role and use of right value reference, derivation of undetermined reference type, and transfer of right value reference
- How to write simple music program with MATLAB
- Vscode的Katex问题:ParseError: KaTeX Parse Error: Can‘t Use Function ‘$‘ In Math Mode At Position ...
- (P19-P20)委托构造函数(代理构造函数)和继承构造函数(使用using)
- MATLAB image processing -- image transformation correction second-order fitting
- C # push box
- Gtest/gmock introduction and Practice
猜你喜欢

Improvement of hash function based on life game

PPP agreement

DUF:Deep Video Super-Resolution Network Using Dynamic Upsampling Filters ... Reading notes

Process terminated

visual studio2019的asp.net项目添加日志功能

MES系统是什么?MES系统的操作流程是怎样?

KAtex problem of vscade: parseerror: KAtex parse error: can't use function '$' in math mode at position

Prediction of COVID-19 by RNN network

Instructions spéciales pour l'utilisation du mode nat dans les machines virtuelles VM

Vins technical route and code explanation
随机推荐
企业上MES系统的驱动力来自哪里?选型又该注意哪些问题?
Pytorch profiler with tensorboard.
2.2 linked list - Design linked list (leetcode 707)
"Three.js" auxiliary coordinate axis
MFC中窗口刷新函数详解
uni-app用canvas截屏并且分享好友
FPGA to flip video up and down (SRAM is61wv102416bll)
OpenMP task 原理與實例
Principes et exemples de tâches OpenMP
qt. qpa. plugin: Could not load the Qt platform plugin “xcb“ in “***“
Improvement of hash function based on life game
Architecture and performance analysis of convolutional neural network
Special notes on using NAT mode in VM virtual machine
Pytorch installation (GPU) in Anaconda (step on pit + fill pit)
802.11 protocol: wireless LAN protocol
Quaternion Hanmilton and JPL conventions
(P33-P35)lambda表达式语法,lambda表达式注意事项,lambda表达式本质
CMAKE 里PRIVATE、PUBLIC、INTERFACE属性示例详解
Principle and example of OpenMP task
数据库基础——规范化、关系模式