Both forms perform initialization. The first syntax (with ()
) is called direct-initialization syntax. The second syntax (with =
) is called copy-initialization syntax. They will act same in most real-life cases, but there are indeed differences between the two.
In situations when types on the left-hand side (LHS) and right-hand side (RHS) are identical (ignoring any const/volatile qualifiers), both are indeed exactly the same. The language standard explicitly states that in this case the =
form is equivalent to ()
form.
But when the types are different (and the LHS type is a class type), these two forms will generally work differently.
The copy-initialization form works as follows: convert the RHS value to the temporary object of LHS type (by any means possible: standard conversion, conversion operator, conversion constructor). And then use the copy constructor of the LHS class to copy the temporary object to the LHS object.
The direct initialization form work as follows: just consider all constructors of LHS and choose the most appropriate one by using overload resolution.
You can immediately notice that the copy-initialization syntax unconditionally uses the copy constructor (the copying and the intermediate temporary can be optimized away, but conceptually they are there). If the LHS class has no accessible copy-constructor, the copy-initialization unconditionally becomes ill-formed, while direct-initialization might still work.
Also, the keyword explicit
applied to certain constructor will affect which form of initialization is available for which combinations of types.