There is the following piece of code
#include <iostream>
class A {
public:
A() {}
// Explicit move constructor
A(A&&) noexcept {
std::cout << "move ctor" << std::endl;
}
// Copy constructor is deleted
A(const A&) = delete;
char x;
};
A a;
A foo() {
A a;
return a; // Return by value, let the compiler apply move semantics
}
A bar() {
return a; // Return by value, let the compiler apply move semantics
}
int main() {
A a = foo(); // Explicit move of the returned object
A a2 = bar();
}
using the following arguments for compilation --std=c++17 -fno-elide-constructors example Inside foo since copy elision is disabled based on standard if x is move-eligible, the expression x is an rvalue. Otherwise, it is an lvalue.
Based on this the move constructor is called .
For the bar the return value is a which has static storage. For this, the move constructor is not implicitly called . It is needed explicity use move. My question is why this difference based on if storage of variable a?
My question is why this difference based on if storage of variable a?
Because it would be fatal if simply writing return a;
in a function meant that a
's state will be lost next time it is used. Imagine you have
std::vector<int> x;
std::vector<int> f() { return x; }
would then want that x
will become empty each time f
is called?
The only reason that it makes sense to automatically move local variables with automatic storage duration is that we know that they can't be used anymore once the function exits.