Suppose I have this function:
void my_test()
{
A a1 = A_factory_func();
A a2(A_factory_func());
double b1 = 0.5;
double b2(0.5);
A c1;
First grouping: it depends on what A_factory_func
returns. The first line is an example of copy initialization, the second line is direct initialization. If A_factory_func
returns an A
object then they are equivalent, they both call the copy constructor for A
, otherwise the first version creates an rvalue of type A
from an available conversion operators for the return type of A_factory_func
or appropriate A
constructors, and then calls the copy constructor to construct a1
from this temporary. The second version attempts to find a suitable constructor that takes whatever A_factory_func
returns, or that takes something that the return value can be implicitly converted to.
Second grouping: exactly the same logic holds, except that built in types don't have any exotic constructors so they are, in practice, identical.
Third grouping: c1
is default initialized, c2
is copy-initialized from a value initialized temporary. Any members of c1
that have pod-type (or members of members, etc., etc.) may not be initialized if the user supplied default constructors (if any) do not explicitly initialize them. For c2
, it depends on whether there is a user supplied copy constructor and whether that appropriately initializes those members, but the members of the temporary will all be initialized (zero-initialized if not otherwise explicitly initialized). As litb spotted, c3
is a trap. It's actually a function declaration.