Skip to main content
added 72 characters in body
Source Link
user17732522
  • 78k
  • 3
  • 82
  • 147

The result object of a function call is initialized by copy-initialization from the operand of the return statement. That's the same initialization that you would have e.g. for a function parameter or for initialization with = initializer syntax.

If the operand is a xvalue, such as std::move(tmp), but in a return statement also just tmp, then itcopy-initialization will result in an attempt to implicitly convert the operand to Foo, which results in an attempt toa call to the copy constructor, because implicit conversions docopy-initialization generally does not consider explicitexplicit constructors., just the same as in

Foo a;
Foo b = std::move(a);

or

void f(Foo);    

Foo a;
f(std::move(a));

If however the return statement's operand is a prvalue such as Foo(std::move(tmp)), then copy-initialization means that the object will be initialized from the initializer of the prvalue. (So-called "mandatory copy elision".) The initialization of the prvalue Foo(std::move(tmp)) is direct-initialization. So the result object of the function call will be initialized by direct-initialization from the argument list (std::move(tmp)). That's the difference to earlier where it was copy-initialized from std::move(tmp).

In direct-initialization all constructors are considered against the argument list and so the explicit move constructor may be chosen. In this case std::move(tmp) is also required, because tmp is only automatically a xvalue in a return statement if it is the whole operand.

That's the same behavior as e.g. in

Foo a;
Foo b = Foo(std::move(a));

or

void f(Foo);    

Foo a;
f(Foo(std::move(a)));

The result object of a function call is initialized by copy-initialization from the operand of the return statement. That's the same initialization that you would have e.g. for a function parameter or for initialization with = initializer syntax.

If the operand is a xvalue, such as std::move(tmp), but in a return statement also just tmp, then it will result in an attempt to implicitly convert the operand to Foo, which results in an attempt to call the copy constructor, because implicit conversions do not consider explicit constructors.

If however the return statement's operand is a prvalue such as Foo(std::move(tmp)), then copy-initialization means that the object will be initialized from the initializer of the prvalue. (So-called "mandatory copy elision".) The initialization of the prvalue Foo(std::move(tmp)) is direct-initialization. So the result object of the function call will be initialized by direct-initialization from the argument list (std::move(tmp)). That's the difference to earlier where it was copy-initialized from std::move(tmp).

In direct-initialization all constructors are considered against the argument list and so the explicit move constructor may be chosen. In this case std::move(tmp) is also required, because tmp is only automatically a xvalue in a return statement if it is the whole operand.

The result object of a function call is initialized by copy-initialization from the operand of the return statement. That's the same initialization that you would have e.g. for a function parameter or for initialization with = initializer syntax.

If the operand is a xvalue, such as std::move(tmp), but in a return statement also just tmp, then copy-initialization will result in a call to the copy constructor, because copy-initialization generally does not consider explicit constructors, just the same as in

Foo a;
Foo b = std::move(a);

or

void f(Foo);    

Foo a;
f(std::move(a));

If however the return statement's operand is a prvalue such as Foo(std::move(tmp)), then copy-initialization means that the object will be initialized from the initializer of the prvalue. (So-called "mandatory copy elision".) The initialization of the prvalue Foo(std::move(tmp)) is direct-initialization. So the result object of the function call will be initialized by direct-initialization from the argument list (std::move(tmp)). That's the difference to earlier where it was copy-initialized from std::move(tmp).

In direct-initialization all constructors are considered against the argument list and so the explicit move constructor may be chosen. In this case std::move(tmp) is also required, because tmp is only automatically a xvalue in a return statement if it is the whole operand.

That's the same behavior as e.g. in

Foo a;
Foo b = Foo(std::move(a));

or

void f(Foo);    

Foo a;
f(Foo(std::move(a)));
Source Link
user17732522
  • 78k
  • 3
  • 82
  • 147

The result object of a function call is initialized by copy-initialization from the operand of the return statement. That's the same initialization that you would have e.g. for a function parameter or for initialization with = initializer syntax.

If the operand is a xvalue, such as std::move(tmp), but in a return statement also just tmp, then it will result in an attempt to implicitly convert the operand to Foo, which results in an attempt to call the copy constructor, because implicit conversions do not consider explicit constructors.

If however the return statement's operand is a prvalue such as Foo(std::move(tmp)), then copy-initialization means that the object will be initialized from the initializer of the prvalue. (So-called "mandatory copy elision".) The initialization of the prvalue Foo(std::move(tmp)) is direct-initialization. So the result object of the function call will be initialized by direct-initialization from the argument list (std::move(tmp)). That's the difference to earlier where it was copy-initialized from std::move(tmp).

In direct-initialization all constructors are considered against the argument list and so the explicit move constructor may be chosen. In this case std::move(tmp) is also required, because tmp is only automatically a xvalue in a return statement if it is the whole operand.