What is the colon syntax (:) in the class constructor and what does passing an integer to a std::vector<> constructor do?
I'd like to explain the below example from this duplicate question:
class UnionFind {
public:
UnionFind(int sz) : root(sz) {
for (int i = 0; i < sz; i++) {
root[i] = i;
}
}
private:
vector<int> root;
};
int main() {
UnionFind uf(10);
}
The colon (:) signifies the start of an "initialization list", or "initializer list", which initializes each variable to the value in parenthesis. It is as though you were calling a constructor for each variable with that value in parenthesis being passed in to that variable's constructor.
So, : root(sz) initializes the root variable with an int sz, which is like doing vector<int> root(sz);. Doing it like this, however, allows sz to get passed in to the UnionFind class constructor.
Initializing a vector with a size like that is constructor #3 here (https://en.cppreference.com/w/cpp/container/vector/vector):
// Constructor (3) as shown at
// https://en.cppreference.com/w/cpp/container/vector/vector
explicit vector( size_type count,
const T& value = T(),
const Allocator& alloc = Allocator());
It constructs count (sz in the example above) number of elements into the vector, each with value T(), which means int() in this case since root is a vector<int>. int() looks like a function call but is basically an integer default constructor to value zero (0). It is called "value initialization". Think of it like calling an "integer constructor", if integers were objects and had constructors. See also my question here: What is a call to char() as a function in C++?
So, let's recap: : root(sz) in the constructor is like constructing vector<int> root(sz);, which creates sz number of elements in the root vector, each with initial value int(), which is the syntax for "value initialization" of an int to zero.
Note also that the count parameter passed to constructor #3 shown above really should be a size_type, which can be written as std::vector::size_type, and is usually size_t (see the "Member types" section here). So, it would be better to change int sz to size_t sz instead. Therefore, change this constructor line: UnionFind(int sz) : root(sz) { to this instead: UnionFind(size_t sz) : root(sz) {.