Is x = std::move(x) undefined?

后端 未结 3 1811
孤街浪徒
孤街浪徒 2020-12-28 11:43

Let x be a variable of some type that has been previously initialized. Is the following line:

x = std::move(x)

undefined? Wher

3条回答
  •  我在风中等你
    2020-12-28 11:58

    All that does is call X::operator=(X&&) (with an lvalue qualified "*this").

    On primitive types, std::move does little of interest, and does not interact with = at all. So this only applies to objects of class type.

    Now, for a type within std (or generated by one of its templates), objects moved from tend to be left in an unspecified (yet valid) state. This is not undefined behavior, but it isn't useful behavior.

    The semantics of a each given X::operator=(X&&) would have to be examined, examining every type within std would be "too broad" for a stack overflow answer. They even may contradict themselves.

    In general, when moveing from an object, you are communicating to the consumer that "you don't care what state the object is in afterwards". The use of a x = std::move(x) is thus impolite, as you (usually) do care what state x is in after the operation completes (as you are assigning to it). You are using the same object as both an lvalue and an rvalue within the same operation, and that is not good a practice.

    An interesting exception is the default std::swap, which goes something like this:

    template
    void swap(T& lhs, T& rhs) {
      T tmp = std::move(lhs);
      lhs = std::move(rhs);
      rhs = std::move(tmp);
    }
    

    the middle line, lhs = std::move(rhs), does an x = std::move(x) if you call swap twice on the same object.

    Note, however, that we do not care what state x is in after this line is completed; we have already stored the state of x in tmp, and we will restore it on the next line.

提交回复
热议问题