I just felt the need for another silly litb post.
string str1 = "foo";
is called copy-initialization, because what the compiler does, if it doesn't elide any temporaries, is:
string str1(string("foo"));
beside checking that the conversion constructor used is implicit. In fact, all implicit conversions are defined by the standard in terms of copy initialization. It is said that an implicit conversion from type U to type T is valid, if
T t = u; // u of type U
is valid.
In constrast,
string str1("foo");
is doing exactly what is written, and is called direct initialization. It also works with explicit constructors.
By the way, you can disable eliding of temporaries by using -fno-elide-constructors:
-fno-elide-constructors
The C++ standard allows an implementation to omit creating a temporary which
is only used to initialize another object of the same type. Specifying this
option disables that optimization, and forces G++ to call the copy constructor
in all cases.
The Standard says there is practically no difference between
T a = u;
and
T a(u);
if T and the type of u are primitive types. So you may use both forms. I think that it's just the style of it that makes people use the first form rather than the second.
Some people may use the first in some situation, because they want to disambiguate the declaration:
T u(v(a));
migh look to someone as a definition of a variable u
that is initialized using a temporary of a type v
that gets a parameter for its constructor called a
. But in fact, what the compiler does with that is this:
T u(v a);
It creates a function declaration that takes a argument of type v
, and with a parameter called a
. So people do
T u = v(a);
to disambiguate that, even though they could have done
T u((v(a)));
too, because there are never parentheses around function parameters, the compiler would read it as a variable definition instead of a function declaration too :)