1

Add element at the end Adds a new element at the end of the vector, after its current last element. The content of val is copied (or moved) to the new element.

Hi, the above is from http://www.cplusplus.com/reference/vector/vector/push_back/

I am a little bit confused by the word "move".I understand the rvalue reference and lvalue reference.

for example,

vector<int> source = {1,2,3};
vector<int> copy;
copy.push_back(source[0]);
cout<<source[0];   // why it doesn't throw error since source[0] is moved to copy ?

because source[0] is rvalue, so push_back actually moves source[0] rather than copy it. Then after this operator, access to source[0] is still valid? why?

Lin Paul
  • 49
  • 8
  • ".I understand the rvalue reference and lvalue reference" what is source[0]? what is std::move(source[0])? – UKMonkey Aug 12 '19 at 01:08
  • 1
    `source[0]` is not an rvalue. It is an lvalue. Even if it was, you are assuming that accessing a moved-from object "throws an error". The C++ standard doesn't require that, in any shape, matter, or form. It might throw an error, for some arbitrary class, but it may not. The C++ standard does not require either one or the other. – Sam Varshavchik Aug 12 '19 at 01:14
  • Could this be a duplicate of https://stackoverflow.com/q/2275076/7363404? I'm not too sure.. – Axiumin_ Aug 12 '19 at 01:15
  • Thank you for replying. I thought source[0] was syntax-sugar of function call, just like calling addInt(2,3) for ```int addInt(int i,inj);``` . But someone told me below that the return value type is reference, then source[0] is lvalue type, which makes sense to me. Otherwise, it will be rvalue type. – Lin Paul Aug 12 '19 at 04:21
  • "why it doesn't throw error since source[0] is moved to copy" - In many cases you shouldn't assume something wrong in C++ will always throw an error. If you have undefined behavior, your program could crash, appear to work, or do anything else. – eesiraed Aug 12 '19 at 04:30

2 Answers2

4
copy.push_back(source[0]);

This passes a const lvalue reference to the function. As such, std::vector is not allowed to touch it; and is forced to copy. This will keep source[0] valid.

copy.push_back(std::move(source[0]));

Will pass an rvalue to the function. This can then be passed into the constructor of the object, and moved.

To follow up though; attempting to use an object that has been moved will usually not error for std objects; because it should leave the object in an "empty" state. You're also using int, which isn't an object, and as such can't really be moved.

UKMonkey
  • 6,941
  • 3
  • 21
  • 30
  • 1
    An `int` is absolutely an object. However you are right in that moving an `int` is not meaningful as it owns no resources and a copy is really all we can do. – Lightness Races in Orbit Aug 12 '19 at 01:17
  • 1
    @LightnessRacesinOrbit I've never heard primitive types called an object before... got a reference? – UKMonkey Aug 12 '19 at 01:18
  • 3
    @UKMonkey [[intro.object](http://eel.is/c++draft/intro.object#1)] in the standard, [object](https://en.cppreference.com/w/cpp/language/object) at cppreference might be more readable. – Blastfurnace Aug 12 '19 at 01:55
  • 1
    @UKMonkey Types are types, not objects. But if you have a line of code that says `int a;`, then `a` is an object of type `int`. It is a particular region of storage that has a name, a type, a size, a lifetime, a value, and so on. – David Schwartz Aug 12 '19 at 02:55
0

because source[0] is rvalue

No, the expression source[0] is lvalue, since the index operator [] of a vector returns a lvalue reference of the element type. See this link.

why it doesn't throw error since source[0] is moved to copy ?

No, the behavior of a moved object is user defined. You can make it throw an error, or you can make operations fail silently, etc. For a scalar (in your case int), move constructing usually leaves the original object untouched.

ph3rin
  • 4,426
  • 1
  • 18
  • 42
  • Thank you. I think my mistake is that I don't know ```[]``` operator returns reference. So, I thought ```source[0]``` as rvalue :( – Lin Paul Aug 12 '19 at 04:24