This is the original GotW problem and solution substantially as posted to Usenet. See the book Exceptional C++ (Addison-Wesley, 2000) for the most current solutions to GotW issues #1-30. The solutions in the book have been revised and expanded since their initial appearance in GotW. The book versions also incorporate corrections, new material, and conformance to the final ANSI/ISO C++ standard.
Difficulty: 4 / 10
How many ways are there to initialize variables? Don't forget to watch out for bugs that look like variable initialization, but aren't.
What is the difference, if any, between the following?
SomeType t = u;
Taking them in reverse order:
The variable t is initialised using the default ctor SomeType::SomeType().
This was a trick; it might look like a variable declaration, but it's a function declaration for a function t that takes no parameters and returns a SomeType.
This is direct initialisation. The variable t is initialised using SomeType::SomeType(u).
SomeType t = u;
This is copy initialisation, and the variable t is always initialised using SomeType's copy ctor. (Even though there's an "=" there, that's just a syntax holdover from C... this is always initialisation, never assignment, and so operator= is never called.)
Semantics: If u also has type SomeType, this is the same as "SomeType t(u)" and just calls SomeType's copy ctor. If u is of some other type, then this is the same as "SomeType t( SomeType(u) )"... that is, u is converted to a temporary SomeType object, and t is copy-constructed from that.
Note: The compiler is actually allowed (but not required) to optimize away the copy construction in this kind of situation. If it does optimize it, the copy ctor must still be accessible.
[Guideline] Prefer using the form "SomeType t(u)". It always works wherever "SomeType t = u" works, and has other advantages (for instance, it can take multiple parameters).