Dlaczego w standardzie std :: span brakuje operatorów porównania?

10

Czy nie zostało std::spanzaprojektowane jako lekkie odniesienie do podregionów std::vector/ std::array/ plain array i podobnych? Czy nie powinien zawierać operatorów porównania w interfejsie API, aby był z nimi spójny? Jakie było uzasadnienie wyłączenia?

Uwaga: przez operatorów porównania, to znaczy albo pełny zestaw ( <, <=...) lub statek kosmiczny<=>

GreenScape
źródło
Świetne pytanie IMO, zastanawiam się nad tym samym. operator==brakuje również. Esp. dla wektora często uważam, że wygodne jest bezpośrednie porównywanie. Może to być spowodowane problemami z typowymi rozpiętościami wielkości, chociaż nie jestem pewien.
darune
Wygląda na to, że gsl :: span, z którego wersją jest std :: span, również ich nie zawiera.
darune
1
@DanielLangr, dlaczego nie porównanie leksykograficzne, takie jak std::vectori std::arrayzrobić? Są już tak zdefiniowane dla tych typów, więc dlaczego nie tutaj.
Timo
2
Należy zauważyć, że P0122R7 proponuje porównanie span, ale obecny projekt standardu go nie obejmuje.
Daniel Langr
1
@darune gsl::span ma (i zawsze miał) operatory porównania. Po prostu przenieśli je do własnego nagłówka
Barry

Odpowiedzi:

3

Jak wskazał Daniel Langr , std::spanma operatorów porównania w swojej pierwotnej propozycji P0122 . Operatory te są następnie usuwane od wersji roboczej N4791 , a przyczyny podano w P1085 .

Krótko mówiąc, copy i const dla std::spansą „płytkie” (co oznacza, że ​​kopiowanie std::spannie kopiuje jego podstawowych elementów, a const std::spannie zapobiega modyfikacji jego podstawowych elementów), więc porównania, jeśli istnieją, powinny być również „płytkie” dla spójności.

W tym dokumencie podano następujące przykłady:

Przykład 1:

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

Przykład 2:

void read_only(const T & x);

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

Twierdzenia w tych przykładach mogą się nie powieść, jeśli T = std::span, podczas gdy nie dotyczy to zwykłych typów.

Można argumentować, że std::string_viewma płytką kopię, ale głębokie porównania. P1085 ma również wyjaśnienie tego:

To pasuje string_view, jednak string_viewnie może modyfikować elementów, na które wskazuje, dlatego płytką kopię string_viewmożna uznać za podobną do optymalizacji kopiowania przy zapisie.

xskxzr
źródło
Zauważ, że nic nie stoi na przeszkodzie, aby właściciel tablicy znaków zmodyfikował oryginalne miejsce przechowywania, std::string_viewwskazując je. Powiedzmy, że std::map<std::span<T>, U>jest tak samo zepsuty jak std::map<std::string_view, U>. IMHO std::string_viewnie powinien również zawierać operatorów porównania.
Lyberta