int ** i
is a pointer to a pointer.
Generally, use this sparingly, as this may have different meanings and you have better ways to express that in C++.
It may be a pointer to single variable containing a pointer to a single int:
int value = 0;
int * pValue = &value;
int ** ppValue = &pValue;
However, each may also be a pointer to the first element of an array:
int valuesA[1000], valuesB[100], valuesC[10];
int * pValues[] = { valuesA, valuesB, valuesC };
// these are actually pointers to the first element of the array
int ** ppValues = pValues;
Use this only with clear documentation how to access elements, how to know the element sizes, and who is responsible for freeing (if any), how long the pointers are valid etc.
Usually, if you have such an array / matrix, you certainly should wrap it behind a safe-to-use interface, or replace it alltogether e.g. with a vector<vector<int>>
.
Even for the single-int use cases there are usually better options. E.g. a function signature that allows to modify a pointer, a reference to a pointer would be more suitable:
bool SelectValue(int *& p) { ... }
int && is a rvalue reference.
Unlike the int **
, this is not a double indirection.
It is, roughly a reference that can also bind to a temporary value.
("Normal" references cannot).
A Brief Introduction to Rvalue References