当前位置:网站首页>(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
边栏推荐
- (P25-P26)基于非范围的for循环、基于范围的for循环需要注意的3个细节
- Leetcode notes: Weekly contest 280
- Xiaomi mobile phone recording data set software operation
- Record the treading pit of grain Mall (I)
- 如何理解APS系统的生产排程?
- In depth learning, the parameter quantity (param) in the network is calculated. The appendix contains links to floating point computations (flops).
- Improvement of hash function based on life game
- Compiling principle on computer -- functional drawing language (I)
- Quaternion Hanmilton and JPL conventions
- Vision transformer | arXiv 2205 - TRT vit vision transformer for tensorrt
猜你喜欢

Vision Transformer | CVPR 2022 - Vision Transformer with Deformable Attention

Record the treading pit of grain Mall (I)

MATLAB image processing -- image transformation correction second-order fitting

APS究竟是什么系统呢?看完文章你就知道了

Mathematical knowledge - derivation - Basic derivation knowledge

"Three.js" auxiliary coordinate axis

数据库基础——规范化、关系模式

(P17-P18)通过using定义基础类型和函数指针别名,使用using和typedef给模板定义别名

EasyExcel导出Excel表格到浏览器,并通过Postman测试导出Excel【入门案例】

Derivation of Poisson distribution
随机推荐
Convolutional neural network CNN based cat dog battle picture classification (tf2.1 py3.6)
Transformation from AC5 to AC6 (1) - remedy and preparation
MES系统质量追溯功能,到底在追什么?
Mathematical Essays: Notes on the angle between vectors in high dimensional space
tmux常用命令
vm虚拟机中使用NAT模式特别说明
『Three.js』辅助坐标轴
Talk about the four basic concepts of database system
Vision Transformer | CVPR 2022 - Vision Transformer with Deformable Attention
Servlet
Solve mapper duplication problem in reverse engineering
PPP agreement
Compiling principle on computer -- functional drawing language (I)
Conda crée un environnement virtuel pour signaler les erreurs et résoudre les problèmes
Windows10 configuration database
Leetcode notes: Weekly contest 279
Search and rescue strategy of underwater robot (FISH)
Leetcode notes: biweekly contest 71
Model Trick | CVPR 2022 Oral - Stochastic Backpropagation A Memory Efficient Strategy
ASP.NET项目开发实战入门_项目六_错误报告(自己写项目时的疑难问题总结)