Home > Blockchain >  Vector of objects without a default constructor and iterator
Vector of objects without a default constructor and iterator

Time:03-11

I am learning to use C vectors, and I can't quite understand the output of the following program:

#include <iostream>
#include <vector>

using namespace std;

class Custom {
public:
    int v;

    Custom() = delete;

    explicit Custom(int v) : v{v} {};

    Custom(const Custom &) : v{4} {

    }

    friend ostream &operator<<(ostream &os, const Custom &th) {
        os << "V is " << th.v << endl;
        return os;
    }
};


int main(int argc, char *argv[]) {
    vector<Custom> c(2, Custom(3));
    c[0].v = 5;

    for (auto i: c) {
        cout << i << endl;
    }

}

I expected it to produce the output

V is 5
V is 4

But instead it produces

V is 4

V is 4

Am I missing something obvious? Thanks.

CodePudding user response:

This range based loop is making copies:

for (auto i: c) {
    cout << i << endl;
}

And the copy constructor initializes v to 4 (and does not make a copy):

Custom(const Custom &) : v{4} {

}

You can either implement a proper copy constructor or use references in the loop to get the desired output:

for (const auto& i: c) {
    cout << i << endl;
}

I would suggest to do both, because this copy constructor is not doing a copy by any means. The compiler generated copy constructor should be fine:

Custom(const Custom &) = default;

PS: The fact that Custom has a deleted default constructor is not really relevant for the posted code. Nowhere in the code a Custom is default constructed. Also there is no iterator in your code. In the range based loop i is a copy/reference of the elements in the vector, it is not an iterator.

CodePudding user response:

When you wrote:

for (auto i: c) //this uses copy constructor to copy initialize each element one by one from the vector
{

}

In the above snippet, each individual element of the vector is used to copy initiaize a temporary object named i while iterating through the vector. And since you have the v{4} in the constructor initializer list of the copy constructor you get the mentioned output.

To solve this you should replace: auto i: c with auto &i: c or const auto &i: c as shown below:

for (const auto &i: c) 
{
   cout << i << endl;
}

Now the elements of the vector are not copied into i. Instead they are references to the object themselves and so you'll get your expected output.

  • Related