Because you do not pass the object's address (a pointer). You pass the object itself (via a reference). Ampersand in the declaration of function argument is the syntax to distinguish that you want the object itself rather than a copy.
// This will copy the pairs
void inpu_c(vector<vector<int>> pairs){
}
// This will work on the original object
void inpu_r(vector<vector<int>> &pairs){
}
The pointer can be used as a reference type, you can dereference it and use the original object itself.
// This will work on the pointer
void inpu_p(vector<vector<int>>* pairs){
pairs->clear();
(*pairs).clear();
// You can even use a reference type inside, you have to dereference a pointer
assert(pairs); //Some protection against invalid pointers
// a reference type requires an object
vector<vector<int>>& r = *pairs;
// will clear object pointer by pairs
r.clear();
}
Using pass-by-value and pass-by-copy semantics do not change the client syntax though. The client code looks the same. That is why you don't have to use get-address operator (&
) on the call site.
Pointers are slightly different from references, those two are different data types. E.g. pointer is nullable, i.e. has a special designated invalid value, while reference is designed to always point to an object.