Search code examples
c++stdvector

Vector of objects without a default constructor and iterator


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.


Solution

  • 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.