Por que std :: span não possui operadores de comparação?

10

Não foi std::spanconcebido como uma referência leve para sub-regiões de std::vector/ std::array/ array simples e similares? Ele também não deve conter operadores de comparação em sua API, para ser consistente com eles? Qual foi o raciocínio por trás da exclusão?

Nota: por operadores de comparação, quero dizer quer o conjunto completo ( <, <=...) ou a nave espacial<=>

GreenScape
fonte
Grande pergunta IMO, eu estou querendo saber o mesmo. operator==também está faltando. Esp. para vetor, costumo achar conveniente comparar diretamente. Talvez devido a dificuldades, talvez com os tipos de tamanho estático, embora não tenha certeza.
darune
Parece que o gsl :: span, do qual o std :: span é versionado, também não os inclui.
darune
11
@DanielLangr Por que não uma comparação lexicográfica gosta std::vectore std::arrayfaz? Eles já estão definidos assim para esses tipos, então por que não aqui?
Timo
2
Observe que P0122R7 propõe comparação para span, mas o rascunho do padrão atual não o inclui.
Daniel Langr 11/03
11
O @darune gsl::span tem (e sempre teve) operadores de comparação. Eles apenas os moveram para o seu próprio cabeçalho
Barry

Respostas:

3

Como Daniel Langr apontou , std::spantem operadores de comparação em sua proposta inicial P0122 . Esses operadores são removidos desde o rascunho de trabalho N4791 , e os motivos estão indicados na P1085 .

Em resumo, copiar e const for std::spansão "superficiais" (ou seja, copiar a std::spannão copia seus elementos subjacentes e uma const std::spannão impede que seus elementos subjacentes sejam modificados); portanto, as comparações, se existir, também devem ser "superficiais" para consistência.

Esse documento fornece os seguintes exemplos:

Exemplo 1:

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

Exemplo 2:

void read_only(const T & x);

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

As asserções nesses exemplos podem falhar se T = std::span, embora isso não ocorra nos tipos regulares.

Pode-se argumentar que std::string_viewtem cópia superficial, mas comparações profundas. O P1085 também tem uma explicação para isso:

Isso corresponde string_view, no entanto, string_viewnão pode modificar os elementos para os quais aponta e, portanto, a cópia superficial string_viewpode ser considerada semelhante a uma otimização de cópia na gravação.

xskxzr
fonte
Observe que nada impede que o proprietário da matriz de caracteres modifique o armazenamento original enquanto std::string_viewaponta para ele. Então, digamos, std::map<std::span<T>, U>está tão quebrado quanto std::map<std::string_view, U>. IMHO, std::string_viewnão deve conter operadores de comparação também.
Lyberta 18/03