Copy constructor and returning by value

Viewed 72

I'm learning about return value optimization and copy elision in C++ and wrote a test vector class to experiment with it in which I allocate memory for an integer array in the constructor:


    //Constructor:
    Vector::Vector(int s): elem{new double[s]}, sz{s} {std::cout << "Constructor called"<<std::endl;}
      
    //Destructor:
    Vector::~Vector(){
        delete[] elem;
        std::cout << "Destructor is called" << std::endl;
    }
    
    double& Vector::operator[](int i){ return elem[i];}
    
    //Move constructor:
    Vector::Vector(Vector&& v): elem{v.elem}, sz{v.sz} 
    {
    std::cout << "Move constructor is called" << std::endl;
        v.elem = nullptr;
        v.sz=0;
    }
    
    //Copy constructor:
    Vector::Vector(Vector& v): elem{v.elem }, sz{v.sz} 
    {
    std::cout << "Copy constructor is called" << std::endl;
    }

In a main file I write a function in which I create a vector from an integer array and return it by value:


    Vector make(int s,int array[]){
    
    Vector v(s);
    
    for(int i =0; i<s; i++){
    v[i] = array[i];
    }
    
    return v;
    }

I call this in the main function as follows:


    int main(){
    
    int a[] = {1,2,3,4};
    
    Vector v = make(4,a);
    
    return 0;
    }

When I then use the compiler option -fno-elide-constructors the move constructor gets called when returning from function. If I get what is written in this post: move constructor called on return instead of copy, the first thing the compiler tries to do is to use the move constructor and when this is not available it uses the copy constructor. So I thought that if I deleted the move constructor:

  Vector(Vector&&)=delete;

the copy constructor would be used as a last resort. If I do this however, the compiler complains that

error: use of deleted function ‘Vector::Vector(Vector&&)’

Vector v = make(4,a);

I wonder if someone can explain to me what is going on here? I know it's probably what I would want to do, but is it possible to make the copy constructor being called when returning the object from the function?

1 Answers

copy constructor should have a const parameter :

Vector::Vector(const Vector& v)

without it cannot accept a rvalue than make return

Related