complx two = complx(3,4);
This is a copy-initialization. The particular semantics for this initializer are covered by this rule:
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 [...] 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). [...]
That is, a copy-initialization where the source type is the same as the destination type behaves like a direct-initialization. So that makes the declaration equivalent to:
complx two(complx(3,4));
This constructs a temporary complx
object and then uses the copy/move constructor to construct two
.
However, this copy/move may be elided:
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
However, the copy constructor must still be accessible, as though it were being called.
Can the two initializations be distinguished? Assuming the copy/move is valid, not reliably, no. If the compiler does elide the copy in the copy-initialization or if the copy is well behaved and doesn't have any extra side effects, then both will behave exactly the same. If it does not elide the copy and the copy has some extra side effects, then you will notice a difference.