Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

When to use std::move ​ in C++

2025-01-14 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >

Share

Shulou(Shulou.com)06/01 Report--

This article mainly explains "when to use std::move in C++". The content in the article is simple and clear, and it is easy to learn and understand. Please follow the editor's train of thought to study and learn when to use std::move in C++.

ES.56: use std::move only when you need to explicitly move an object to another scope

Reason (reason)

We use move instead of copy to avoid unnecessary duplication and improve performance.

Moving operations generally leave an empty object (C.64), which can be misleading or even dangerous. So we try to avoid moving left values (they may be used in subsequent code).

Notes (Note)

If the source data is a right value, the move operation takes place implicitly (such as return processing or the return value of the function), in which case the explicit move operation can cause the code to be aimlessly complicated. Instead, write a short function with a return value so that both the return value of the function and the acceptance action on the calling side can be naturally optimized.

In general, following the guidelines in this document (including not to expand the scope of variables unnecessarily, writing short functions with return values, returning local variables, etc.) can help eliminate most of the need to explicitly perform std::move.

Explicit movement is necessary when explicitly moving an object to another scope. In particular:

1. When passing an object to a "sink" function (a function that takes over the ownership of a variable)

two。 When implementing the object's own move operation (move constructor, move assignment operator) and exchange operation

Example, bad (negative example)

Void sink (X & x); / / sink takes ownership of x

Void user ()

{

X x

/ / error: cannot bind an lvalue to a rvalue reference

Sink (x)

/ / OK: sink takes the contents of x, x must now be assumed to be empty

Sink (std::move (x))

/ /...

/ / probably a mistake

Use (x)

}

Typically, std::move () serves as an argument to the & & parameter. And after moving, you should assume that the object has been removed (see C.64) and do not get the state of the object until a new value is assigned.

Void f () {

String S1 = "supercalifragilisticexpialidocious"

String S2 = S1; / / ok, takes a copy

Assert (S1 = = "supercalifragilisticexpialidocious"); / / ok

/ / bad, if you want to keep using s1s value

String S3 = move (S1)

/ / bad, assert will likely fail, s1 likely changed

Assert (S1 = = "supercalifragilisticexpialidocious")

} Example (example) void sink (unique_ptr p); / / pass ownership of p to sink ()

Void f () {

Auto w = make_unique ()

/ /...

Sink (std::move (w)); / / ok, give to sink ()

/ /...

Sink (w); / / Error: unique_ptr is carefully designed so that you cannot copy it

} Notes (note)

Std::move () is actually a type conversion aimed at & &; it doesn't move anything by itself, but marks the named object as a candidate for a move operation. The language already knows the general situation in which objects can be removed, especially the return value of a function, so don't complicate the code with extra std::move.

Never use std::move just because you hear it's more efficient. Don't usually trust the so-called "efficiency" that deviates from specific data. Don't usually complicate your code for no reason. Never call std::move () on a constant object, which will unwittingly produce a copy.

Example, bad (negative example)

Vector make_vector () {

Vector result

/ /... Load result with data

Return std::move (result); / / bad; just write "return result;"

}

Never return the result of a move of a local variable; because the language already knows that this variable can be used as a candidate for a move operation, adding move code to this kind of code not only does not help, but for some compilers, adding move code will affect the normal execution of RVO (return value optimization) due to the generation of additional references to local variables.

Example, bad (negative example)

Vector v = std::move (make_vector ()); / / bad; the std::move is entirely redundant

If the function f returns the result by passing a value, never call a move operation on that return value, such as X=move (f ()); the language already knows that the return value is a temporary variable and can be removed.

Example (sample)

Void mover (X & x) {

Call_something (std::move (x)); / / ok

Call_something (std::forward (x)); / / bad, don't std::forward an rvalue reference

Call_something (x); / / suspicious, why not std::move?

}

Template

Void forwarder (tipped & t) {

Call_something (std::move (t)); / / bad, don't std::move a forwarding reference

Call_something (std::forward (t)); / / ok

Call_something (t); / / suspicious, why not std::forward?

} Enforcement (implementation recommendations)

Tag calls std::move for a right value or an object that has been regarded as a right value by the language. Includes std::move (local_variable);, std::move (f ()), where f is a function that returns the result by passing a value.

The tag does not have a const S & type overloaded function to handle the left value, only in the case of a function that handles the right value (parameter type: slots &).

Tag passes the result of the std::move execution to the parameter, unless the parameter type is the right-value reference type Xcopy, or the parameter type is move-only, not copied, and passed by value.

The case where the tag calls std::move on the reference type of the care (where T is the template parameter).

The tag std::move is used in situations other than right-value references to non-constant variables. (a more general form of the previous rule to include non-handover parameters)

Mark the case where std::forward is used for right-value references (X is the specific type), and use std::move instead.

The tag std::forward is used to refer to situations other than references. (a more general form of the previous rule, which can override cases of non-moving parameters. )

The tag object may be removed and the next is a constant operation; where there should be a non-constant operation in the first place, it is best to reset the assignment of the object value.

Thank you for reading, the above is the content of "when to use std::move in C++". After the study of this article, I believe you have a deeper understanding of the question of when to use std::move in C++, and the specific use needs to be verified in practice. Here is, the editor will push for you more related knowledge points of the article, welcome to follow!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Internet Technology

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report