This question is about the wording of the c++ standard.
All compilers, and I think this is what should be, elide the copy constructor for the initialization of the object b
bellow (assembly here):
struct B;
struct A{
operator B();
};
struct B{
B(const B&);
B(B&&);
};
void test(A a){
B b(a);
}
But when I read the standard, I do not see why this elision shall happen (bold mine) [dcl.init]/17.6.2:
Otherwise, if the initialization is direct-initialization, [...], constructors are considered. The applicable constructors are enumerated ([over.match.ctor]), and the best one is chosen through overload resolution ([over.match]). 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.
It is specifically said that the constructor is called. But no compiler does it.
I imagine I am missing something or not reading correctly the standard. How should I read the standard?
This contrast with the previous and next paragraphs of the standard that specifically mandate copy elision [dcl.init]/17.6.1:
If the initializer expression is a prvalue and the cv-unqualified version of the source type is the same class as the class of the destination, the initializer expression is used to initialize the destination object.
and [dlc.init]/17.6.3:
Otherwise (i.e., for the remaining copy-initialization cases), user-defined conversions that can convert from the source type to the destination type [...] The function selected is called with the initializer expression as its argument; [...] The call is used to direct-initialize, according to the rules above, the object that is the destination of the copy-initialization.
Where the last sentence send me back to [dcl.init]/17.6.1 which would also implies the copy elision.