If you use a prvalue expression to copy initialize a variable, and that variable has the same type as the prvalue expression, then the copying can be elided.
std::string str = std::string("foo");
Copy initialization effectively transforms this into std::string str("foo");
(there are minor differences).
This also works with return values:
std::string func()
{
return std::string("foo");
}
std::string str = func();
Without copy elision, this would provoke 2 calls to std::string
's move constructor. Copy elision permits this to call the move constructor 1 or zero times, and most compilers will opt for the latter.