0

Let's say I have an object

class A {
    public:
    int bar();
};

A foo() {return A();}
int A::bar() {return 5;}

And then I do this:

int i = foo().bar();

What constructor is invoked for the temporary value created when foo() returns?

jaggedSpire
  • 4,423
  • 2
  • 26
  • 52
Sebastian Lenartowicz
  • 4,695
  • 4
  • 28
  • 39
  • 3
    The question can just be reduced to `A foo() { return A(); }`, none of the rest is relevant. And then... which constructor do you think? It's easy to simply instrument and find out. Do you question the results you got? – Barry Aug 10 '16 at 20:34
  • @Barry not necessarily easy to find by testing, because of copy elision – M.M Aug 10 '16 at 21:59
  • As I've found out - my problem was caused by copy elision. – Sebastian Lenartowicz Aug 10 '16 at 22:01

3 Answers3

1

The code is:

A foo() {return A();}

When foo() is called , the sequence of effects is:

  1. Temporary created by A() using A's default constructor.
  2. Return value object of type A created using copy/move constructor, with step 1's temporary as argument (that is, move constructor if it exists, otherwise copy constructor).
  3. Temporary from step 1 is destructed.

However this is a copy elision context, so the compiler might combine all 3 steps into one, and create the return value object using A's default constructor.

What happens to the return value object depends on what the calling code does. There might be further copy elision. In the usage:

int i = foo().bar();

nothing else happens; bar() is called on the return value object, the value is assigned to i, and then the return value object is destroyed.

Community
  • 1
  • 1
M.M
  • 138,810
  • 21
  • 208
  • 365
0

If you are compiling with C++11, inside foo when return A() ran it calls default constructor. Then when it returns from foo move constructor is called. But if you're compiling with older versions first default constructor is called then copy constructor is called.

halit
  • 177
  • 7
0

The default constructor is called. Maybe trying this makes it clearer:

#include <iostream>

using namespace std;

class A {
public:
  A() {
    cout << "A's default ctor" << endl;
  }
};

int main() {
  A a;
  return 0;
}