0

Suppose I have a class Foo. I can imagine two ways of initialization: (i.e., invoking the constructor)

Foo myFooLong = Foo(...args...);
Foo myFooShort(...args...);

Is there any difference in operation (as far as I'm concerned, that's not the case)?

Sanchises
  • 847
  • 4
  • 22
  • In C++03 the copy initialization (first syntax) required an accessible copy constructor. E.g. you could not do that with a `std::ostringstream`, you had to use direct initialization (second syntax). In C++11 it's enough that there's an accessible move constructor. – Cheers and hth. - Alf May 05 '14 at 16:49
  • I think the "which style is generally preferred" is **off topic** in SO, while the "Is there any difference" is on-topic. Please adjust question. – Cheers and hth. - Alf May 05 '14 at 16:51
  • @Cheersandhth.-Alf You're right; I did check but I did not know the term 'Copy initialization'. Should I delete my question, or mark it as duplicate somehow? – Sanchises May 05 '14 at 18:08
  • I don't know if you can vote to close your own question, but if you can, there's only one vote missing. i suggest if you can, vote as duplicate. there are 2 votes as "primarily opinion based", possibly due to the final preference question. – Cheers and hth. - Alf May 05 '14 at 18:31
  • In c++11 you can also do `Foo foo{...args...};` which is the same as your second form but is not at risk of the [most vexing parse](http://en.wikipedia.org/wiki/Most_vexing_parse). Advocates of [AAA](http://herbsutter.com/2013/08/12/gotw-94-solution-aaa-style-almost-always-auto/) suggest `auto foo = Foo{...args...};` – Chris Drew May 05 '14 at 19:27

1 Answers1

0

The statement

  Foo myFooLong = Foo(...args...);

first creates a Foo object (the right side) and then copies it to the left operand using the copy construtor.

The second statement just creates a new Foo object.

There is no reason to prefer the first approach over the second. The first one involves unnecessary temporary creation and copying hence needs an accessible copy constructor ( copy elision may be applied).

Rakib
  • 7,435
  • 7
  • 29
  • 45
  • 1
    Theoretically, yes. In practice, the extra temporary doesn't happen. – Luchian Grigore May 05 '14 at 16:52
  • 1
    -1 re "the first one involves unnecessary temporary creation and copying", that is not the case. when the types are identical the compile has no choice, it must elide the copying. – Cheers and hth. - Alf May 05 '14 at 16:52
  • @Cheersandhth.-Alf where in the standard does it say that the copy must be elided? – Brian Bi May 05 '14 at 16:53
  • @Cheersandhth.-Alf, copy elision is not mandatory and IB. – Rakib May 05 '14 at 16:56
  • Copy-initialization also requires an accessible copy constructor, no matter whether it actually ends up getting called. – Kerrek SB May 05 '14 at 16:59
  • On the other hand, copy initialization lets you write left-to-right: `auto x = Foo(1, 2, 3);`. – Kerrek SB May 05 '14 at 16:59
  • @Brian: I'm unable to find it. I have made similar statements about the elision not being guaranteed and been corrected and I've seen that "fact" (with reference) a number of times, but I'm also unable to find the discussion. :-( So I'm beginning to think that there may possibly not be such a special case. Still, the text in the answer is strongly misleading, if not downright incorrect: I doubt that anyone can produce an example of an implementation where `T x = T(blah)` invokes a final copy construction. – Cheers and hth. - Alf May 05 '14 at 17:47
  • I did use an empty "hello world" constructor to try whether the default constructor was called (which wasn't the case), so this is indeed resolved by copy elision on my compiler. Thanks. – Sanchises May 05 '14 at 18:10