Mengapa std :: span tidak memiliki operator pembanding?

10

Bukankah itu std::spandirancang sebagai referensi ringan untuk sub-daerah arraystd::vector / std::array/ dan sama-sama? Bukankah seharusnya juga memuat operator perbandingan di API-nya, agar konsisten dengan mereka? Apa alasan di balik pengecualian ini?

Catatan: oleh operator perbandingan, maksud saya baik set lengkap ( <, <=, ...) atau pesawat ruang angkasa<=>

GreenScape
sumber
Pertanyaan bagus IMO, saya juga bertanya-tanya. operator==juga hilang. Esp. untuk vektor saya sering merasa nyaman untuk membandingkan secara langsung. Bisa jadi karena kesulitan mungkin dengan jenis rentang ukuran statis, meskipun saya tidak yakin.
darune
Sepertinya gsl :: span, dari mana std :: span diversi dari tidak menyertakan ini juga.
darune
1
@DanielLangr mengapa bukan perbandingan leksikografis suka std::vectordan std::arraylakukan? Mereka sudah didefinisikan seperti itu untuk tipe-tipe itu, jadi mengapa tidak di sini.
Timo
2
Perhatikan bahwa P0122R7 mengusulkan perbandingan span, tetapi standar konsep saat ini tidak memasukkannya.
Daniel Langr
1
@ Darune gsl::span memang (dan selalu) memiliki operator pembanding. Mereka baru saja memindahkan mereka ke header
Barry

Jawaban:

3

Seperti yang ditunjukkan Daniel Langr , std::spanmemiliki operator pembanding dalam proposal awal P0122 . Operator-operator ini kemudian dihapus sejak draft kerja N4791 , dan alasannya dinyatakan dalam P1085 .

Singkatnya, copy dan const std::spanadalah "dangkal" (artinya menyalin a std::spantidak menyalin elemen-elemen yang mendasarinya, dan sebuah const std::spantidak mencegah elemen-elemen yang mendasarinya untuk dimodifikasi), jadi perbandingan, jika ada, juga harus "dangkal" untuk konsistensi.

Makalah itu memberikan contoh-contoh berikut:

Contoh 1:

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

Contoh 2:

void read_only(const T & x);

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

Pernyataan dalam contoh-contoh ini mungkin gagal jika T = std::span, sementara itu tidak untuk tipe reguler.

Orang mungkin berpendapat bahwa std::string_viewmemiliki salinan dangkal tetapi perbandingan yang mendalam. P1085 juga memiliki penjelasan untuk ini:

Ini cocok string_view, namun string_viewtidak dapat memodifikasi elemen yang ditunjuknya, dan dengan demikian salinan dangkal string_viewdapat dianggap mirip dengan optimasi copy-on-write.

xskxzr
sumber
Perhatikan bahwa tidak ada yang mencegah pemilik array karakter untuk memodifikasi penyimpanan asli sambil std::string_viewmenunjuk ke sana. Jadi, katakanlah, std::map<std::span<T>, U>sama rusaknya dengan std::map<std::string_view, U>. IMHO, std::string_viewtidak boleh mengandung operator pembanding.
Lyberta