1

I was looking at one of the answers on Stack Overflow to create a class for a 2d Vector. The solutions involved initialising the inner vector while the outer vector was being created.

class A{
public:
   A(int dim1,int dim2):v(dim1,std::vector<int>(dim2)){}
private:   
   std::vector< std::vector<int> > v;
};

class A{
public:
   A(int dim1,int dim2){v.resize(dim1,std::vector<int>(dim2));}
private:   
   std::vector< std::vector<int> > v;
};

I understood that a vector can be initialised like this

size=4; value =10; std::vector<int> A (size,value);

However I dont have an intuitive sense as to how can a vector be initialised like std::vector (size), with the variable object absent, as is happening while setting dim2 in the initial code snippet. Am I missing something?

  • 2
    `I was looking at one of the answers on Stack Overflow` Which one? Link it. – Keith M Jan 08 '18 at 19:38
  • 2
    [**C++ - value of uninitialized vector**](https://stackoverflow.com/questions/5222404/c-value-of-uninitialized-vectorint) – Sandra K Jan 08 '18 at 19:39
  • 1
    [Look at the documentation, and pay attention to constructor (2)](http://en.cppreference.com/w/cpp/container/vector/vector). See the second argument is a default? – PaulMcKenzie Jan 08 '18 at 19:41
  • 2
    Since you're also calling `resize`, [look at the docs here](http://en.cppreference.com/w/cpp/container/vector/resize). Note the second argument? – PaulMcKenzie Jan 08 '18 at 19:44
  • 1
    @PaulMcKenzie It seems to me that the OP is trying to make sense of constructor (3). – Bob__ Jan 08 '18 at 19:45
  • I don't understand what you mean by "with the variable object absent". Do you mean the `value` field in your example? – Keith M Jan 08 '18 at 19:49

2 Answers2

3

To start off conceptually, v(dim1, X) sets v to size dim1 and initializes all the values to X. Since v is of type std::vector< std::vector<int> >, X must be of type std::vector<int>.

std::vector<int>(dim2) does just that, creating an in-line std::vector<int> of size dim2, and initializes all the values to 0, as per the SO question and documentation provided in the comments here and here. (Constructor #3 is used here, not #2.)

The result, therefore, is a dim1 by dim2 std::vector< std::vector<int> >, with all the int variables inside initialized to 0.

Keith M
  • 853
  • 10
  • 28
  • So when you're calling std::vector (size), you are calling the constructor of the class std::vector, passing size as an argument to the constructor and then this vector object returned by the constructor is being passed as the second argument? – Krishna Toshniwal Jan 09 '18 at 01:19
  • @KrishnaToshniwal Yes, that's right. Constructor #2 (the outer one) makes copies of `const T& value` to put into its elements. Then, in your case, what you passed in gets deallocated when the whole line is finished, as is true whenever you just plain call a constructor... that is, without calling it on an object (which I believe is considered bad practice anyway; make a "(re)initialize" function or something instead, and call that from the constructor too). – Keith M Jan 24 '18 at 00:09
2

When you initialize a std::vector with size, but no value argument, all of the instances of the object are value initialized. For class types, this means calling the default constructor, for primitive types and aggregates this means everything will be set to zero.

Unless you use a special allocator, or you are using a class type that has a user written constructor that fails to initialize some of the members (which is real bad), it's not possible to have anything be uninitialized when using a vector.

Here's the doc: http://en.cppreference.com/w/cpp/container/vector/vector. It shows that the constructor only taking a size does "default insertion". And as this page: http://en.cppreference.com/w/cpp/concept/DefaultInsertable discusses, "default insertion" with the default allocator (and most allocators) calls placement new, which does value initialization.

In this specific case, the inner vector is a vector of integers, and the outer vector is a vector of vectors of integers. So that means that:

  1. The outer vector will consist of dim1 copies of the same (in the value, not identity sense; they are distinct vectors but populated the same) vector.
  2. The inner vector will consist of dim2 integers, all with value 0.
Nir Friedman
  • 17,108
  • 2
  • 44
  • 72