7

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 1s.

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 Rectangles instead of ints:

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 4s 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?

2 Answers 2

7

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.

Sign up to request clarification or add additional context in comments.

7 Comments

Note that constructor's signature changed since C++11, it doesn't have the default argument T() now.
@Adam I agree with songyuanyao. Adam, please also see the tiny green mark on the link "until C++11" and "since C++11". The std::vector behavior can be different in different C++ version.
@songyuanyao Does that means it's not 0 in c++11?
@bigxiao The effect should be same.
@songyuanyao Why does the c++11 does not specify an default allocator<T> ,like the c++17 does? Does that mean it does not use an allocator in c++11?
|
3

A little tinkering with your prameterized constructor can solve the problem. We have to just provide default parameter here.

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

Now, if we call std::vector arr(20); it will execute properly and give your desired output.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.