Why does returning a std::optional sometimes move and sometimes copy?

Because returning a name of an object with automatic storage duration is treated as returning an rvalue of the object. Note this works only if the expression in the return statement is a (possibly parenthesized, not including braces) name, like return u; or return (u);, so return {u}; works as usual, i.e. the copy constructor is invoked.

Related part in the standard [class.copy.elision]/3:

In the following copy-initialization contexts, a move operation might be used instead of a copy operation:

  • If the expression in a return statement ([stmt.return]) is a (possibly parenthesized) id-expression that names an object with automatic storage duration declared in the body or parameter-declaration-clause of the innermost enclosing function or lambda-expression, or

overload resolution to select the constructor for the copy is first performed as if the object were designated by an rvalue.

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)