When designing a function that expects a contiguous array in the form of a pointer, should one pass the array using
A.
a pointer and the array's size:
void foo(int* arr, size_t size);
Or B.
a begin-pointer and an end-pointer:
void foo(int* arrBegin, int* arrEnd);
Obviously the total size of the parameters are the same in both methods but is there ever a good reason to prefer one over the other? I believe approach A. is the more common one but I see both being used frequently. Could one make more sense in certain contexts, and vice versa? Does one have any drawbacks compared to the other? Or does it just not matter and you should simply choose one approach and stick with it?
There is the general rule of least surprise
If I write a function like (Like @Elijay suggests)
I can be certain that it is well understood by everyone using my function, contiguous container, pointer like argument type etc.
On top of that first, and last is a shoe-in for pretty much all of the standard library algorithms and containers. Very convenient and easy to understand.
My 2¢.