Почему в std :: span отсутствуют операторы сравнения?

10

Разве это не было std::spanразработано как облегченная ссылка на подобласти массиваstd::vector / std::array/ plain ? Разве он не должен содержать операторы сравнения в своем API, чтобы соответствовать им? Что было причиной исключения?

Примечание: операторы сравнения, я имею в виду либо полный набор ( <, <=, ...) или космический корабль<=>

GreenScape
источник
Отличный вопрос IMO, мне интересно то же самое. operator==также отсутствует. Особенно для вектора мне часто удобно сравнивать напрямую. Это может быть связано с трудностями, возможно, со статическими типами размеров диапазона, хотя я не уверен.
Дарун
Похоже, что gsl :: span, откуда взято std :: span, тоже не включает их.
Дарун
1
@DanielLangr, почему не лексикографическое сравнение, как std::vectorи std::arrayделать? Они точно так же определены для этих типов, так почему бы и нет.
Тимо
2
Обратите внимание, что P0122R7 предлагает сравнение для span, но текущий проект стандарта не включает его.
Даниэль Лангр
1
У @darune gsl::span есть (и всегда были) операторы сравнения. Они просто перенесли их в свой заголовок
Барри

Ответы:

3

Как отметил Даниэль Лангр , std::spanоператоры сравнения в своем первоначальном предложении P0122 . Эти операторы затем удаляются с рабочего проекта N4791 , а причины указываются в P1085 .

Короче говоря, copy и const for std::spanявляются «мелкими» (это означает, что копирование a std::spanне копирует свои базовые элементы, а const std::spanне препятствует изменению его базовых элементов), поэтому сравнения, если они существуют, также должны быть «мелкими» для согласованности.

В этой статье приводятся следующие примеры:

Пример 1:

T oldx = x;
change(x);
assert(oldx != x);
return oldx;

Пример 2:

void read_only(const T & x);

void f()
{
  T tmp = x;
  read_only(x);
  assert(tmp == x);
}

Утверждения в этих примерах могут потерпеть неудачу, если T = std::spanэто не так для обычных типов.

Можно утверждать, что std::string_viewимеет мелкую копию, но глубокие сравнения. У P1085 также есть объяснение этому:

Это соответствует string_view, однако string_viewне может изменить элементы, на которые оно указывает, и, таким образом, мелкая копия string_viewможет рассматриваться как подобная оптимизации копирования при записи.

xskxzr
источник
Обратите внимание, что ничто не мешает владельцу символьного массива изменять исходное хранилище, пока оно std::string_viewуказывает на него. Так что, скажем, std::map<std::span<T>, U>сломан как std::map<std::string_view, U>. ИМХО, std::string_viewне должно содержать операторов сравнения.
Либерта