A return statement with
no operand shall be used only in a function whose return type is
cvvoid, a constructor, or a
destructor.
A return statement with an operand of type void shall be used only
in a function whose return type is cvvoid.
A return statement with any other operand shall be used only
in a function whose return type is not cvvoid;
the return statement initializes the
glvalue result or prvalue result object of the (explicit or implicit) function call
by copy-initialization from the operand.
A return statement can involve
an invocation of a constructor to perform a copy or move of the operand
if it is not a prvalue or if its type differs from the return type of the function.
A copy operation associated with a return statement may be elided or
converted to a move operation if an automatic storage duration variable is returned ([class.copy.elision]).
The copy-initialization of the result of the call is sequenced before the
destruction of temporaries at the end of the full-expression established
by the operand of the return statement, which, in turn, is sequenced
before the destruction of local variables ([stmt.jump]) of the block
enclosing the return statement.