Another thing: In the first iteration (high - low) == n, so for even n in your changes the first assignment to `mid` will be off-center. That changes the worst case behaviour a little
There's a common C++ idiom that uses pointers past the end of arrays, too:
| for (T it = begin(foo); it != end(foo); ++it) {
// ...
}
|
This just works in C with arrays and pointers, but in C++ you can overload ++ and != for any type. This became formalised in C++11 with the range based for loop, which just looks for those functions (or methods) and dereferences the iterator for you.
Soapbox: it's one of those things that's really stupid about C++; they have an iterator 'type', the definition of which is implicitly defined by this syntactic expansion. The language update to fix this has been just around the corner for a decade as far as I know. This example happens to be small and baked into the language, but metaprogramming exclusively via duck typing shivers my timbers