Почему предлагаемый `std::shared_ptr:: operator[]` принимает `std:: ptrdiff_t` в качестве аргумента

#c #c 17

#c #c 17

Вопрос:

Согласно предложению N4562, вновь предложенный std::shared_ptr::operator[] принимает std::ptrdiff_t , который является подписанным типом.

Это несовместимо с каждым оператором индексации в стандартной библиотеке. Даже std::unique_ptr::operator[] принимает std::size_t .

В чем причина этого решения?

Комментарии:

1. Может быть, потому, что комитет, наконец, признает, что использование неподписанного типа в качестве индекса было ужасной ошибкой, и они пытаются изменить его на новый материал?

2. И почему именно это ошибка? Например, имеет смысл с std::vector помощью .

3. @bipll тот факт, что попытка выполнить итерацию в обратном направлении — это боль, является хорошим началом. интуитивно вы хотели бы написать for(auto i = cont.size() - 1; i > 0; --i) , но не можете, поскольку он никогда не будет меньше 0.

4. Я собирался предположить, что, поскольку вы можете использовать псевдонимы shared_ptr , в отличие от других контейнеров, ваш shared_ptr может фактически указывать на середину массива, и отрицательная индексация может иметь смысл. Но на самом деле они требуют, чтобы индекс был положительным, поэтому здесь нет смысла использовать подписанный тип. Это кажется просто плохим решением.

5. Интуитивно я бы всегда писал for(auto i(cont.rbegin()) в таком случае.

Ответ №1:

Вероятно, это должно быть объединение интерфейса указателя. Старые добрые указатели C при использовании в качестве массивов принимают отрицательные индексы: p[-2] совпадает с *(p - 2) ; и ptrdiff_t , таким образом, естественно подписывается.

Комментарии:

1. «Требуется: get() != 0 amp;amp; i >= 0 » Вы все равно не можете передать отрицательный индекс.

2. Я тоже так думал, но сомневаюсь в этом — у нас есть приоритет, с std::unique_ptr которым принимает целое число без знака.

3. Тогда это выглядит как несоответствие предложения.

4. @GManNickG Это кажется ненужным ограничением. Вы можете использовать конструктор псевдонимов, чтобы получить указатель на середину массива. ptr[-2] в этом случае имело бы смысл.

5. Вопрос «Зачем использовать тип, который позволяет мне столкнуться с ошибкой?» — это тот же вопрос, который мы всегда слышим. Если вы передаете a -1 , это всегда ошибка, независимо shared_ptr от того, использует или нет int unsigned . Таким образом, в вопросе действительно не должно быть сказано «это позволяет мне столкнуться с ошибкой», но вопрос должен быть «Зачем использовать тип, который позволяет мне обнаружить ошибку, с которой я столкнулся?». Вот почему int лучше </signed-vs-unsigned> .