c++gccc++17copy-elisionelision

Why destructor is called if the return operation is elided?


I have the following code that mimics an elision testcase

class Obj
{
  public:
  int x = 0;
  Obj(int y) : x(y) {std::cout << "C\n"; }
  ~Obj() { std::cout << "D\n"; }
};

auto factory()
{
  std::vector<Obj> vec {1,2,3};
  
  std::cout<< &vec[0] << std::endl;
  
  return vec;
}

int main()
{
    auto vec = factory();
    
    std::cout<< &vec[0] << std::endl;
    
    for(auto& v : vec)
      std::cout << v.x << std::endl;
}

The output is unexpected, tho

C C C D D D

0x5640f1d43e80

0x5640f1d43e80

1 2 3 

D D D

Why Obj destructor is called if there's elision active ?

I see that the memory space of the first item is the same ( and constructor is not called ) So I would imagine that no memory has been copied. But if that's so, why (again) item destructors are called in the first place ?


Solution

  • With the initializer list construction:

    std::vector<Obj> vec {1,2,3};
    

    First the initializer_list is constructed, with all 3 Obj objects. Only then is the constructor of std::vector invoked, coping the three objects. What you see as 3 destructor calls is actually the destruction of the initializer_list, not the vector object (which is in fact elided in this case).