4

Say, I have a class A

Now when I am doing

A a(A()); 

what exactly happens?

fredoverflow
  • 256,549
  • 94
  • 388
  • 662
Kundan Kumar
  • 1,974
  • 7
  • 32
  • 54
  • 1
    I would imagine that would be optimized out if it's not being called. – chris May 29 '12 at 16:54
  • @chris I'm not so sure. The return value optimization (RVO) is permitted, but what about copies within a single function? –  May 29 '12 at 16:55
  • @chris...I know of the copy constructor elison concept for the case A a = A(), in this case the default constructor gets called.But in above case neither default nor copy constructor is getting called – Kundan Kumar May 29 '12 at 16:56
  • possible duplicate of [Most vexing parse: why doesn't A a(()); work?](http://stackoverflow.com/questions/1424510/most-vexing-parse-why-doesnt-a-a-work) – Bo Persson May 29 '12 at 17:01
  • @Bo Persson it ain't a duplicate. `A a(())` and `A a(A())` are different things. –  May 29 '12 at 17:06
  • 2
    @Radek - Read the question, it is all there! "Why doesn't `A a(B())` work?" is a perfect duplicate for "Why doesn't `A a(A())` work?". – Bo Persson May 29 '12 at 17:11
  • @BoPersson: Read the linked question - it's asking why the invalid code `A a(())` (with only one `A`) doesn't compile, and just mentions the "Most Vexing Parse" to set the scene. It's not a duplicate of this question. – Mike Seymour May 29 '12 at 17:34

2 Answers2

11

Despite appearances, A a(A()); is not an object definition. Instead, it declares a function called a that returns an A and takes a pointer to a function taking nothing and returning an A.

If you want an object definition, you have to add another pair of parenthesis:

A a((A()));
fredoverflow
  • 256,549
  • 94
  • 388
  • 662
  • Use `A a{A{}}` in C++11 to call the copy ctor if you don't want an extra set of parenthesis. –  May 29 '12 at 17:00
  • @FredOverflow Can you explain in little detail :) – Invictus May 29 '12 at 17:01
  • @FredOverflow....can you please give an example how to use this function declaration. – Kundan Kumar May 29 '12 at 17:11
  • Since it's only a *declaration*, not a *definition*, you will get a linker error if you try to call the function. Don't get too hung up on this, just add the extra pair of parenthesis and get on with your code ;) – fredoverflow May 29 '12 at 17:16
8

If written correctly - A a((A())) - the compiler creates the temporary directly in the constructor context to prevent an extra copy. It's called copy elision. Look this up, along with RVO and NRVO.

From your comment:

A a = A();

this is exactly equivalent to

A a((A())); // note extra pair of parenthesis 

As @Naveen correctly pointed out, A a(A()); is subject to most vexing parse, so you need an extra set of paranthesis there to actually create an object.

Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625