简体   繁体   English

你如何将左值转换为右值? 而且`new`左值会发生什么?

[英]How do you convert a lvalue to an rvalue? And what happens to the `new` lvalue?

I would like to move an object into a std::vector using std::vector::push_back() . 我想使用std::vector::push_back()将对象移动到std::vector This would seem to be possible since there is a std::vector::push_back(value_type&& val) function. 这似乎是可能的,因为有一个std::vector::push_back(value_type&& val)函数。 But due to the the existence of std::vector::push_back(value_type const & val) , which copies and would be the overriding call, I need to convert the lvalue object to an rvalue. 但由于std::vector::push_back(value_type const & val) ,它复制并将成为重写调用,我需要将左值对象转换为右值。

How is this done? 这是怎么做到的?

Example: 例:

struct X { int x; X(int x) : x(x) {} };

int main()
{
    std::vector<X> ax;
    X x(3);
    ax.push_back(x);  // <= Want to move x in to vector ax, not copy.
    return 0;
}

Actually, maybe it can't be? 实际上,也许它不可能? I ask this because after writing this example, my new questions are: 我问这个是因为写完这个例子后,我的新问题是:

  • If I do move x into ax , what is the value of xx ? 如果我将x移动到axxx的值是多少? If X had an explicit destructor, what would happen to x when it leaves scope? 如果X有一个显式的析构函数, x在离开作用域时会发生什么?

Just use std::move() : 只需使用std::move()

ax.push_back(std::move(x));

Concerning your question: 关于你的问题:

If I do move x into ax, what is the value of xx? 如果我将x移动到ax,xx的值是多少?

In this case, your class X does not contain an explicitly declared move constructor, so the compiler will generate one that does memberwise move of X 's members. 在这种情况下,您的类X不包含显式声明的移动构造函数,因此编译器将生成一个成员移动X的成员。 Since X only has one member of type int , and moving an int is no different from copying it, then xx will have the same value it had before being moved from. 由于X只有一个int类型的成员,并且移动int与复制它没有区别,因此xx将具有与移动之前相同的值。

If X had an explicit destructor, what would happen to x when it leaves scope? 如果X有一个显式的析构函数,x在离开作用域时会发生什么?

If X has a user-declared destructor, that will inhibit the generation of an implicit move constructor - but not that of an implicit copy constructor. 如果X有一个用户声明的析构函数,那将禁止生成隐式移动构造函数 - 但不会生成隐式复制构造函数。 Therefore, this function call: 因此,这个函数调用:

ax.push_back(std::move(x));

Will result in x being copied into ax . 将导致x复制ax In any case, x will be destroyed when going out of scope, since it has automatic storage duration - no matter whether a user-declared destructor is present or not. 在任何情况下, x都会在超出范围时被销毁,因为它具有自动存储持续时间 - 无论是否存在用户声明的析构函数。

In general, one should not make assumptions on the state of an object that has been moved from, except that that state is valid (paragraph 17.6.5.15/1 of the C++11 Standard guarantees this to be the case for types of the Standard Library). 一般来说,不应该对已经移动的对象的状态做出假设,除了该状态是有效的(C ++ 11标准的第17.6.5.15/1节保证了这种情况的类型)标准图书馆)。

In concrete, this means that the only functions that can safely work with an object that has been moved from are those that do not have any precondition on the state of that object . 具体而言,这意味着可以安全地处理已移动对象的唯一函数是那些对该对象的状态没有任何先决条件的函数 Typically, two such functions are the destructor and the (copy- or move-) assignment operator. 通常,两个这样的函数是析构函数和(复制或移动)赋值运算符。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM