Adam Adam - 8 months ago 23
C++ Question

Default values when creating a vector, C++

Consider the following code:

#include <iostream>
#include <vector>
using namespace std;

int main() {
// create a vector with 20 0s
std::vector<int> arr(20);
for (int i = 0; i < arr.size(); i++)
std::cout<<arr[i];
return 0;
}


The above code creates a vector of 20
0
's and prints each one. If I change the constructor to
arr (20,1)
it creates a vector of 20
1
s.

If I define a class:

class Rectangle {
int width, height;
public:
Rectangle (int,int);
int area () {return (width*height);}
};

Rectangle::Rectangle (int a, int b) {
width = a;
height = b;
}


And create a vector of
Rectangle
s instead of
int
s:

int main() {
// create a vector with 20 integer elements
std::vector<Rectangle> arr(20, Rectangle(2,2));
for (int i = 0; i < arr.size(); i++)
std::cout<<arr[i].area();
return 0;
}


Twenty
4
s get printed. However, when I try:

std::vector<Rectangle> arr(20);


I get:

prog.cpp: In constructor 'std::vector<_Tp, _Alloc>::vector(std::vector<_Tp, _Alloc>::size_type, const value_type&, const allocator_type&) [with _Tp = Rectangle; _Alloc = std::allocator<Rectangle>; std::vector<_Tp, _Alloc>::size_type = unsigned int; std::vector<_Tp, _Alloc>::value_type = Rectangle; std::vector<_Tp, _Alloc>::allocator_type = std::allocator<Rectangle>]':
prog.cpp:19:34: error: no matching function for call to 'Rectangle::Rectangle()'
std::vector<Rectangle> arr(20);


Do I need to define a constructor with no arguments to make this work? And in general, what happens when I don't provide a second argument to the
vector
constructor when I'm using non-primitive types?

Answer Source

Do I need to define a constructor with no arguments to make this work?

Yes, see this link : http://en.cppreference.com/w/cpp/container/vector/vector.

Here is the related constructor of std::vector.

explicit vector( size_type count, const T& value = T(), const Allocator& alloc = Allocator());

Without the second parameter, it is assumed to be T() via default parameter.
T() will become Rectangle() in your case.

When you call primitive with std::vector, it will act similar.
Roughly speaking, it will call default-constructor-syntax on the primitive e.g. int(), which yield 0.

This ideone demo shows that int()==0.