I've recently learned about move constructors, but a lot of the online resources don't talk about copy elision. Copy elision makes sense to me too, but it left me wondering when is the move constructor ever going to be called without a super contrived example.
From a popular SO post that explained move semantics to me https://mcmap.net/q/15702/-what-is-move-semantics
string b(x + y);
string c(some_function_returning_a_string());
The post says both of these should invoke the move constructor because they take in temporaries. However, none of these actually call the move constructor (I've tested), instead they all just do copy elision, unless you force it to by explicitly writing std::move
.
string b(std::move(x + y));
string c(std::move(some_function_returning_a_string()));
or some_function_returning_a_string
returns std::move(someString)
. But why would you? Copy elision is even more performant than move semantics. So what are the natural cases where the move constructor would be called instead of copy elision?
Before you point me here, I felt like When Does Move Constructor get called? answer gave either contrived examples or some of them would have just done copy elision. I'm interested in learning when move constructors are called in practice.
Here's a link for the testing https://godbolt.org/z/KfczbboTr
std::vector
. If you exceed capacity it has to allocate new element objects and move the existing ones in there. – Carillonneurvoid Foo(std::string&& s);
may involve a move constructor, or may use a move assignment, or may not move at all — depends on what Foo's implementation does.void Bar(std::string s)
called throughstd::string s = "Hello"; Bar(std::move(s));
will use a move constructor. – Tremaine