静态转换为右值引用和std :: move之间有什么区别吗?

时间:2021-07-25 18:55:48

The description for static cast says

静态演员的描述说

If new_type is an rvalue reference type, static_cast converts the value of expression to xvalue. This type of static_cast is used to implement move semantics in std::move.(since C++11)

如果new_type是右值引用类型,则static_cast将expression的值转换为xvalue。这种类型的static_cast用于在std :: move中实现移动语义。(自C ++ 11起)

Does this confirm that the following are equivalent ?

这是否证实以下内容相同?

(A)

X x1;
X x2 = static_cast<X&&>(x1); 

(B)

X x1;
X x2 = std::move(x1);

3 个解决方案

#1


31  

Yes there is a very important difference: std::move documents what you want to do. In addition the cast is prone to writing errors like a forgotten & or wrong type X.

是的,有一个非常重要的区别:std :: move文件你想做什么。此外,演员很容易写出错误类型X的错误。

As it can be seen, std::move is even less to type.

可以看出,std :: move的输入更少。

#2


1  

T&& In C++11 is rValue reference. They behave like lvalue reference from C++ 98,03. Their goal - to be a candidate for moving. In C++98 such construction can be appear in refrence collapsing

T &&在C ++ 11中是rValue参考。它们的行为类似于C ++ 98,03中的左值引用。他们的目标 - 成为移动的候选人。在C ++ 98中,这样的构造可以出现在refrence崩溃中

std::move - turns expression in rvalue. It could be called rvalue_cast, but such keyword is not exist.

std :: move - 在rvalue中转换表达式。它可以被称为rvalue_cast,但这样的关键字不存在。

Explicit cast to type T&& possible in principle. Real standart cost some money, but in draft of the ISO/IEC 14882:2011 There is exist such info

显式强制转换为类型T &&原则上可行。真正的标准花费了一些钱,但在ISO / IEC 14882:2011的草案中存在这样的信息

5.2.9 Static cast

5.2.9静态铸造

8)  

The lvalue-to-rvalue (4.1), array-to-pointer (4.2), and function-to-pointer (4.3) conversions are applied to the operand....

左值到右值(4.1),数组到指针(4.2)和函数到指针(4.3)转换应用于操作数....

From practical point of view it is more convenient to use std::move. Imagine such example:

从实际的角度来看,使用std :: move更方便。想象一下这样的例子:

#include <stdio.h>
#include <utility>

class A
{
public:
A () {printf ("A ()" "\n");}
A (const A &) {printf ("A (&)" "\n");}
A (A &&) {printf ("A (&&)" "\n");}
A (const A &&) {printf ("A (const &&)" "\n");}
~ A () {printf ("~ A ()" "\n");}
};


int main ()
{
const A obj;
A obj2 (std::move (obj)); // 1-st approach
A obj3 (static_cast <const A&&> (obj));  // 2-nd approach
}

As for me 1-st approach is

至于我的第一种方法是

  • more convenient (should you perform static_cast to const A&&, or to A&& ?)
  • 更方便(你应该执行static_cast到const A &&,还是执行A &&?)

  • more explicitly (I can use search in text-editor to find std::move in project)
  • 更明确(我可以使用文本编辑器中的搜索来查找项目中的std :: move)

  • less error-prone when software developer write code
  • 软件开发人员编写代码时不易出错

#3


-1  

You can use static_cast<A &&>(a) when a is an rvalue, but you shouldn't use std::move(a).
When you use A && a = std::move(A()), you get a dangling reference.

当a是rvalue时,你可以使用static_cast (a),但你不应该使用std :: move(a)。当你使用A && a = std :: move(A())时,你会得到一个悬空引用。

The basic idea is that the lifetime of a temporary cannot be further extended by "passing it on": a second reference, initialized from the reference to which the temporary was bound, does not affect its lifetime.

基本思想是临时的生命周期不能通过“传递”来进一步扩展:从临时绑定的引用初始化的第二个引用不会影响其生命周期。

std::move's implementation is somewhat like

std :: move的实现有点像

template <typename T>
constexpr decltype(auto) move(T && __t) noexcept  // when used in std::move(A()),
                                                  // the lifetime of the temporary object is extended by __t
{
    return static_cast<typename std::remove_reference<T>::type &&>(__t);  // a xvalue returned, no lifetime extension
}

auto && a = std::move(A());  // the anonymous object wiil be destructed right after this line

#1


31  

Yes there is a very important difference: std::move documents what you want to do. In addition the cast is prone to writing errors like a forgotten & or wrong type X.

是的,有一个非常重要的区别:std :: move文件你想做什么。此外,演员很容易写出错误类型X的错误。

As it can be seen, std::move is even less to type.

可以看出,std :: move的输入更少。

#2


1  

T&& In C++11 is rValue reference. They behave like lvalue reference from C++ 98,03. Their goal - to be a candidate for moving. In C++98 such construction can be appear in refrence collapsing

T &&在C ++ 11中是rValue参考。它们的行为类似于C ++ 98,03中的左值引用。他们的目标 - 成为移动的候选人。在C ++ 98中,这样的构造可以出现在refrence崩溃中

std::move - turns expression in rvalue. It could be called rvalue_cast, but such keyword is not exist.

std :: move - 在rvalue中转换表达式。它可以被称为rvalue_cast,但这样的关键字不存在。

Explicit cast to type T&& possible in principle. Real standart cost some money, but in draft of the ISO/IEC 14882:2011 There is exist such info

显式强制转换为类型T &&原则上可行。真正的标准花费了一些钱,但在ISO / IEC 14882:2011的草案中存在这样的信息

5.2.9 Static cast

5.2.9静态铸造

8)  

The lvalue-to-rvalue (4.1), array-to-pointer (4.2), and function-to-pointer (4.3) conversions are applied to the operand....

左值到右值(4.1),数组到指针(4.2)和函数到指针(4.3)转换应用于操作数....

From practical point of view it is more convenient to use std::move. Imagine such example:

从实际的角度来看,使用std :: move更方便。想象一下这样的例子:

#include <stdio.h>
#include <utility>

class A
{
public:
A () {printf ("A ()" "\n");}
A (const A &) {printf ("A (&)" "\n");}
A (A &&) {printf ("A (&&)" "\n");}
A (const A &&) {printf ("A (const &&)" "\n");}
~ A () {printf ("~ A ()" "\n");}
};


int main ()
{
const A obj;
A obj2 (std::move (obj)); // 1-st approach
A obj3 (static_cast <const A&&> (obj));  // 2-nd approach
}

As for me 1-st approach is

至于我的第一种方法是

  • more convenient (should you perform static_cast to const A&&, or to A&& ?)
  • 更方便(你应该执行static_cast到const A &&,还是执行A &&?)

  • more explicitly (I can use search in text-editor to find std::move in project)
  • 更明确(我可以使用文本编辑器中的搜索来查找项目中的std :: move)

  • less error-prone when software developer write code
  • 软件开发人员编写代码时不易出错

#3


-1  

You can use static_cast<A &&>(a) when a is an rvalue, but you shouldn't use std::move(a).
When you use A && a = std::move(A()), you get a dangling reference.

当a是rvalue时,你可以使用static_cast (a),但你不应该使用std :: move(a)。当你使用A && a = std :: move(A())时,你会得到一个悬空引用。

The basic idea is that the lifetime of a temporary cannot be further extended by "passing it on": a second reference, initialized from the reference to which the temporary was bound, does not affect its lifetime.

基本思想是临时的生命周期不能通过“传递”来进一步扩展:从临时绑定的引用初始化的第二个引用不会影响其生命周期。

std::move's implementation is somewhat like

std :: move的实现有点像

template <typename T>
constexpr decltype(auto) move(T && __t) noexcept  // when used in std::move(A()),
                                                  // the lifetime of the temporary object is extended by __t
{
    return static_cast<typename std::remove_reference<T>::type &&>(__t);  // a xvalue returned, no lifetime extension
}

auto && a = std::move(A());  // the anonymous object wiil be destructed right after this line