При работе с массивами стандартные алгоритмы (как на C, так и на С++) часто возвращают указатели на элементы. Иногда бывает удобно иметь индекс элемента, возможно, для индексации в другой массив, и я обычно получаю это путем вычитания начала массива из указателя:
int arr[100];
int *addressICareAbout = f(arr, 100);
size_t index = addressICareAbout - arr;
Это всегда казалось простым и эффективным. Однако недавно мне было указано, что вычитание указателя фактически возвращает a ptrdiff_t
и что в принципе могут возникнуть проблемы, если "index
" не вписывается в ptrdiff_t
. Я действительно не верил, что любая реализация будет достаточно извращенной, чтобы позволить создать такой большой arr (и тем самым вызвать такие проблемы), но принятый ответ здесь допускает что это возможно, и я не нашел доказательств, чтобы предлагать иное. Поэтому я смирился с тем, что это так (если кто-то не убедит меня иначе) и будет осторожным в будущем. Этот ответ предлагает довольно запутанный метод "безопасного" получения индекса; действительно ли ничего лучше?
Тем не менее, я смущен о возможном обходном пути в С++. Мы имеем std::distance
, но std::distance(arr, addressICareAbout)
гарантированно четко определены? С одной стороны, (указатель на первый элемент) arr
может быть увеличен до достижения addressICareAbout
(справа?), Но с другой стороны std::distance
должен вернуть ptrdiff_t
. Итераторы для стандартных контейнеров могут (предположительно) иметь одинаковые проблемы.