¿Por qué std :: span carece de operadores de comparación?

10

¿No fue std::spandiseñado como una referencia ligera para subregiones de std::vector/ std::array/ matriz simple y similares? ¿No debería contener también operadores de comparación en su API, para ser coherentes con ellos? ¿Cuál fue el razonamiento detrás de la exclusión?

Nota: los operadores de comparación, es decir, ya sea el conjunto completo ( <, <=, ...) o de la nave espacial<=>

GreenScape
fuente
Gran pregunta de la OMI, me pregunto lo mismo. operator==También falta. Esp. para el vector, a menudo me parece conveniente comparar directamente. Podría deberse a dificultades, tal vez con los tipos de tramo de tamaño estático, aunque no estoy seguro.
Darune
Parece que gsl :: span, desde el cual se versiona std :: span tampoco incluye estos.
Darune
1
@DanielLangr ¿por qué no una comparación lexicográfica como std::vectory std::arrayhacer? Ya se definen así para esos tipos, entonces, ¿por qué no aquí?
Timo
2
Tenga en cuenta que P0122R7 propone una comparación span, pero el borrador del estándar actual no lo incluye.
Daniel Langr
1
@darune gsl::span tiene (y siempre tuvo) operadores de comparación. Simplemente los movieron a su propio encabezado
Barry

Respuestas:

3

Como señaló Daniel Langr , std::spantiene operadores de comparación en su propuesta inicial P0122 . Estos operadores se eliminan luego del borrador de trabajo N4791 , y las razones se exponen en P1085 .

En resumen, copy y const for std::spanson "superficiales" (lo que significa que copiar un std::spanno copia sus elementos subyacentes, y un const std::spanno evita que se modifiquen sus elementos subyacentes), por lo que las comparaciones, si existen, también deberían ser "superficiales" por consistencia.

Ese documento da los siguientes ejemplos:

Ejemplo 1:

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

Ejemplo 2

void read_only(const T & x);

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

Las afirmaciones en estos ejemplos pueden fallar si T = std::span, mientras que no lo hace para los tipos regulares.

Se puede argumentar que std::string_viewtiene una copia superficial pero profundas comparaciones. P1085 también tiene una explicación para esto:

Esto coincide string_view, sin embargo, no string_viewpuede modificar los elementos a los que apunta y, por lo tanto, la copia superficial de string_viewpuede considerarse similar a una optimización de copia en escritura.

xskxzr
fuente
Tenga en cuenta que nada impide que el propietario de la matriz de caracteres modifique el almacenamiento original mientras lo std::string_viewseñala. Entonces, digamos, std::map<std::span<T>, U>está tan roto como std::map<std::string_view, U>. En mi humilde opinión, std::string_viewtampoco debería contener operadores de comparación.
Lyberta