Birçok standart kitaplık türü için neden C ++ 20'de operatör! = Kaldırıldı?


44

Cppreference göre , std::type_info::operator!=C ++ 20 ile kaldırılır, ancak std::type_info::operator==görünüşe göre kalır.

Arkasındaki sebep nedir? Eşitsizliğin anlamsız olduğunu karşılaştırmayı kabul edebilirim, ama sonra eşitliği karşılaştırmak da anlamsız olurdu, değil mi?

Benzer bir şekilde, operator!=bu gibi kaplar da dahil olmak üzere diğer pek çok standart kütüphane türlerinin std::unordered_map::operator!=ve std::unordered_set::operator!=cppreference göre 20 C ++ kaldırılacaktır.

Yazmak if(!(id1 == id2))zorunda kalmak if(id1 != id2), aksine, herhangi bir kodu daha net yapmaz ...

Yanıtlar:


62

C ++ 20'de ilişkisel operatörlerin çalışma şekli, özellikle uzay gemisi <=>operatörünün tanıtılmasıyla değiştirildi . Özellikle, sadece sağlarsanız operator==, o a != bzaman yeniden yazılır !(a == b).

Gönderen [over.match.oper] /3.4 :

Yeniden yazılan aday seti şu şekilde belirlenir:

  • İlişkisel ([expr.rel]) operatörler için, yeniden yazılan adaylar x <=> y ​​ifadesi için yeniden yazılmamış tüm adayları içerir.
  • İlişkisel ([expr.rel]) ve üç yönlü karşılaştırma ([expr.spaceship]) operatörleri için, yeniden yazılan adaylar ayrıca, yeniden yazılmayan her aday için, ifade y <=> x.
  • ! = İşleci ([expr.eq]) için, yeniden yazılan adaylar x == y ifadesi için yeniden yazılmamış tüm adayları içerir.
  • Eşitlik operatörleri için, yeniden yazılan adaylar ayrıca y == x ifadesi için yeniden yazılmamış her aday için iki parametrenin sırasını tersine çevirerek sentezlenmiş bir aday içerir.
  • Diğer tüm operatörler için yeniden yazılan aday seti boştur.

Ve [over.match.oper] / 9 :

Yeniden yazılmış bir operatör == adayı bir operatör @ için aşırı yük çözünürlüğü ile seçilirse, dönüş türü cv bool olmalı ve x @ y şu şekilde yorumlanır:

  • @ ise! = ise ve seçilen aday tersine çevrilmiş parametre sırasına sahip sentezlenmiş bir adaysa! (y == x),
  • aksi takdirde, @!!,,! (x == y) ise ,
  • aksi takdirde (@ == olduğunda), y == x,

her durumda seçilen yeniden yazılmış operatörü == aday kullanarak.

Bu nedenle, için açık bir aşırı yükleme operator!=artık gerekli değildir. Operatörün kaldırılması karşılaştırma semantiğini değiştirmedi.

Anlayabildiğim operator!=kadarıyla tüm kaplar çıkarılmıştı (örneğin vektör sinopsisini kontrol edin ). Tek istisna konteyner adaptörleridir std::queueve std::stack: tahminim, eşitlik operatörlerinin simetrik olmaması durumunda üçüncü taraf konteynerlerle kullanıldığında geriye dönük uyumluluğu korumaktır.


7
Aşırı yüklenmeleri kaldıran teklifin bu olduğuna inandığım için p1614 de ilgi çekici olabilir.
N. Shead

39

operator!=Artık bir kütüphaneye ihtiyacımız yok. Sağlanması operator==derleyici sağlar biraz hokkabazlık yapmak ve değerlendirmek için a != baçısından a == btüm kendi başına.

[Over.match.oper]

3 cv-kalifiye olmayan sürümü T1 olan bir tür işleneni olan tekli bir operatör @ ve cv-kalifiye olmayan sürümü T1 olan bir sol işleneni ve cv- niteliksiz versiyon T2'dir, dört aday fonksiyon seti, belirlenmiş üye adayları, üye olmayan adaylar, yerleşik adaylar ve yeniden yazılan adaylar aşağıdaki gibi oluşturulur:

3.4.3 ! = İşleci ([expr.eq]) için, yeniden yazılan adaylar x == y ifadesi için yeniden yazılmamış tüm adayları içerir.

std::type_infove daha birçok kütüphane türü P1614 - Mothershipoperator!= in Land'in bir parçası olarak kaldırıldı .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.