In the code below an object s
of class S
is used to initialize an object of class D
with a direct-initialization D d(s);
. The conversion function S::operator D() is used to convert the object s
into a temporary object of type D
. Then, gcc and clang both elide the explicit call to the move constructor D(&&)
, to move this temporary object into d
. See live example.
#include <iostream>
struct D;
struct S{ operator D(); };
struct D{
D(){}
D(D&&) { std::cout << "move constructor" << '\n'; }
};
S::operator D() { std::cout << "conversion function" << '\n'; return D(); }
int main()
{
S s;
D d(s);
}
I'm disputing the correctness of this elision, on the following grounds:
If the initialization is direct-initialization, or if it is copy-initialization where the cv-unqualified version of the source type is the same class as, or a derived class of, the class of the destination, constructors are considered. The applicable constructors are enumerated (13.3.1.3), and the best one is chosen through overload resolution (13.3). The constructor so selected is called to initialize the object, with the initializer expression or expression-list as its argument(s). If no constructor applies, or the overload resolution is ambiguous, the initialization is ill-formed.
The C++ standard loves to create exceptions to rules defined in one place in a completely different place.
The copy/move elision rules are specified in 12.8/31. There are two copy/move operations to be eliminated in your code.
The first is easy: within operator D
, the temporary constructed in the return expression is moved to the temporary that represents the function return value. Bullet 3 permits elision of this move.
The second is the move of the temporary function return value to the d
object. Again, bullet 3 permits the elision.
- when a temporary class object that has not been bound to a reference (12.2) would be copied/moved to a class object with the same cv-unqualified type, the copy/move operation can be omitted by constructing the temporary object directly into the target of the omitted copy/move
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With