Initialization is the process of giving an object its first value. For objects generated from structs and classes, initialization is performed by constructors. — Scott Meyers – Effective C++ (3rd Edition)
#Initialization using the vector fill constructor (identical values)
A std::vector can be initialized using the std::vector fill constructor if we need a vector containing M elements that are all equal to a given value or object.
#include <vector>
// myCnt will contain M integers equal to 0
std::vector myCnt(M, 0);
// myCnt2 will contain M integers equal to -5
std::vector myCnt2(M, -5);
#Filling a vector using the std::iota() function (increasing values)
The std::iota() function is very useful when we need to fill a vector with an increasing group of values.
#include <vector> // std::vector
#include <iostream> // std::cout
#include <numeric> // std::iota
int main() {
std::vector<int> myCnt(20,0); // fill constructor -> real initialization
std::iota(myCnt.begin(), myCnt.end(), -10);
std::cout << "myCnt: ";
for (int& i : myCnt) std::cout << ' ' << i;
std::cout << std::endl;
return 0;
}
myCnt: -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9
Press any key to continue . . .
The std::iota() does not allocate memory. For this reason, we need to construct the vector as shown previously.
This function operates on a user-defined range and it overwrites already existing values with the new ones.
#Filling a vector using the std::generate() function (random values)
We can fill a vector using the function std::generate(). For each element of the vector, this function executes a user-defined method to return (and assign) a certain object/value. For example, for each element of the vector, a random integer value can be returned and assigned to each vector element.
In the example below, we are generating a vector of values randomly chosen between 0 and 99:
#include <vector>
#include <iostream> // std::cout
#include <algorithm> // std::generate
#include <ctime> // std::time
// This function returns a random number
int RandomNumber() { return (std::rand() % 100); }
int main() {
// Vector fill constructor --> the real initialization
std::vector<int> myCnt2(20);
// Overwriting the vector elements with random values
std::generate(myCnt2.begin(), myCnt2.end(), RandomNumber);
// Printing values
std::cout << "myCnt2: ";
for (int& i : myCnt2) std::cout << ' ' << i;
std::cout << std::endl;
return 0;
}
The code above will print something like (the values are not guaranteed to be unique.):
myCnt2: 78 63 38 71 65 69 83 83 1 16 26 30 59 12 19 60 46 1 60 90
Press any key to continue . . .
NOTE: Basing on the definition given by Scott Meyers, the procedures described in the last two sections cannot be seen as a pure initialization because the vector has been already constructed to contain a certain number of elements. The vector elements are assigned after this stage. For this reason, the term “filling” – rather than initialization – seems more correct to me.
