Question: I'm building some `std::vector<Obj>` where `Obj` are large objects which can be move constructed and assigned (think eg of `Obj` being large vectors). The code is typically a loop such as

```
std::vector<Obj> v;
while (...) {
    Obj foo = some client code(...);
    // ... some complicated stuff modifying foo
    v.push_back(foo);
}

```

As you can see, `foo` is not needed after being pushed in the vector.

My questions are

* Does is make sense to write

```
  v.push_back(std::move(foo));

```

to indicate to the compiler that it can take the contents of foo.
* if it does, is it actually needed ? Indeed the compiler might notice that `foo` is destructed right after being pushed so that it can be moved... Does actual compilers use those kinds of optimisation ?

Answer: 
The compiler is not allowed to call the move constructor or elide the objects without you explicitly moving (ie, casting to an rvalue reference; possibly by std move) except under very specific situations.

A) the object is a temporary unnamed object.

B) The object is being returned from a function.

There are a few other requirements, but neither of the above two apply here. So no conversion to move/elision allowed.

The complier can sometimes use the as-if rule to turn a copy and later destroy into a move, but that is very difficult and often fragile, so you should not ever rely on it.
Whether or not the compiler can optimize it depends on exactly what `Obj` looks like, what functions you call when doing "complicated stuff modifying `foo`", whether `Obj` has a move constructor, and so on. You should try to compile and benchmark the code and see for yourself, or use an online service like <https://godbolt.org/> to see what assembler code is produced.

However, the best way is to avoid copying or moving altogether. You can do this by calling [`emplace_back()`](https://en.cppreference.com/w/cpp/container/vector/emplace_back) to construct an `Obj` directly in the vector, and then modify it in place, like so:

```
while (...) {
    v.emplace_back();
    Obj &foo = v.back();
    // ... some complicated stuff modifying foo
}

```

And you can write this slightly shorter with C++17:

```
while (...) {
    Obj &foo = v.emplace_back();
    // ... some complicated stuff modifying foo
}

```