2013-07-23 34 views
6

operatör> ve operatör < tanımlanan Zaten varsa (ve operatör ==), ben operatör> = ve operatörü < = tanımlamak gerekiyor veya derleyici onları benim için ilan edecek kasıtlı olarak onları bildirmezseniz? Ben operatör == tanımlı varsa daEl ile bildirmek zorunda mıyım> = ve <= operatörler?

, derleyici benim için operatör! = ilan edecek?

+2

Eğer işleç <'ve işleç ==' tanımlanmış, sağlamak için ['std :: rel_ops'] (http://en.cppreference.com/w/cpp/utility/rel_ops/operator_cmp) ad alanında sürükleyebilirsiniz operatörlerin geri kalanı, ama bu gerçekten iyi bir çözüm değil (http://stackoverflow.com/questions/62 25375/idiomatic kullanım-içinde-stdrel-op). [Boost.Operators] (http://stackoverflow.com/a/14756785/241631) bunu yapmanın doğru yolu. – Praetorian

+0

Sadece bir kaç operatör yazarak kaydetmek için miras kullanarak bir şey değil. Onları elle eklemek isterim. =) –

+0

, işlevselliği sağlayan bir sınıftan türeterek, büyük bir dokümantasyon değerine de sahiptir. Kavramların ilkel bir şeklidir. – TemplateRex

cevap

6

Hayır, Derleyici el ile tanımlamadığınız operatörleri açıklamıyor/tanımlamıyor. Ancak, Boost.Operators sizin beğeninize olabilir - tam olarak derleyicinin yapmasını istediğiniz şeyi yapar.

+0

Dang. İyi varsayılan kopya-kurucular ve benzeri üretirler. Basit bir otomatik oluşturulan * operatörün umuyordum! = (Diğer) {dönüş! (* Bu == diğer); } *. Oh, cevabınız için teşekkürler!Kabul etmeden önce biraz bekleyeceğim. –

+1

+1 Boost.Operators (Daniel Frey) 'in koruyucusu, kütüphanenin C++ 11'e [df.operators] (https://github.com/d-frey/operators) adındaki resmi bir bağlantı noktasına sahiptir (rvalue aşırı yükler ve noexcept) – TemplateRex

5

derleyici burada sizin için bir şey kendisi yapmayacağım ama gelen uygun bir sınıfını miras yoluyla otomatik olarak üretmek için nispeten basit bir şey gibi:

template< typename DerivedType > 
class ComparisonOperators 
{ 
public: 

    friend bool   operator!=( 
          DerivedType const& lhs, 
          DerivedType const& rhs) 
    { 
     return !(lhs == rhs); 
    } 

    friend bool   operator<=( 
          DerivedType const& lhs, 
          DerivedType const& rhs) 
    { 
     return !(rhs < lhs); 
    } 

    friend bool   operator>( 
          DerivedType const& lhs, 
          DerivedType const& rhs) 
    { 
     return rhs < lhs; 
    } 

    friend bool   operator>=( 
          DerivedType const& lhs, 
          DerivedType const& rhs) 
    { 
     return !(lhs < rhs); 
    } 

protected: 
         ~ComparisonOperators() {} 
} ; 

Sınıfındaki < ve == tanımlayın

class MyClass : public ComparisonOperators<MyClass> 
{ 
    // ... 
public: 
    bool operator==(MyClass const& other) const; 
    bool operator<(MyClass const& other) const; 
    // ... 
}; 

Sadece bir not: ve operatörlerin tüm alırsınız bu türer ve el ı Actu versiyonunu basitleştirdik diğerleri de == ve < tanımlar , üye için fonksiyonları compare ve isEqual görünen ve hiçbir isEqual olduğunda == ve != için compare kullanır kullanımı. Sanırım herhangi bir hata yaptı, ama asla bilemezsiniz.

+0

Bir negatif, pozitif veya 0 değeri (geleneksel C yaklaşımı) döndüren bir "int karşılaştırması (DerivedType const & o)" seçeneğini tercih etme eğilimindeyim. Genellikle '==' ve '<' çok benzer kodlardır, bu yüzden onları birleştirmek güzeldir. –

+3

Bu, Boost.Operators'ın sizin için tam olarak yaptığı şey değil mi? ;-) –

+0

@ edA-qamort-ora-y Evet. Yukarıdaki 'karşılaştır' için imza budur. Kural: sadece eşitlik için karşılaştırma: 'isEqual' (ve ilişkisel operatörler, kullanıldıklarında derleme yapamaz); eşitlik ve ilişkisel, 'karşılaştır'ı kullan; _if_ eşitliği çok daha hızlı yapılabilir, o zaman ikisini de sağlayabilirsiniz. Ve doğru olanı arayacak olan ComparisonOperators sınıfında bir miktar meta programlama var. –

0

Burada boost ve devralma kullanarak bazı iyi yanıtlar var. Ama birinin belirttiği gibi - operatörün yaratılması için miras kullanmak ... yanlıştır.

C++ 'da "tabu" olan #define s olduğunu biliyorum, ama yine de burada kullanıyorum.

benim genel yarar bir #define olduğunu böyle gider şunlardır:

#define CREATE_COMPARITORS(name)        \ 
inline bool operator>(const name &o){return o<*this;}   \ 
inline bool operator<=(const name &o){return not (o<*this);} \ 
inline bool operator>=(const name &o){return not (*this<o);} \ 
inline bool operator!=(const name &o){return not (*this==o);} 

Sonra bir sınıf varsa, ben beyan gereken operator< ve operator== geçerli:

class ttt{ 
    //... 
    bool operator<(const ttt &o); 
    bool operator==(const ttt &o); 
    CREATE_COMPARITORS(ttt); 
    //... 
}; 
+0

Bunu haklı çıkarmanız gerekebilir "gibi görünüyor" ... yanlış. " Şu an itibariyle kütüphane tasarımcılarına haksız görüşünüzden daha çok güveniyorum. – djechlin

+0

Bu iş parçasında bir başkasını alıntılıyordu: "Bir şey, birkaç operatör yazmayı kaydetmek için miras kullanarak yanımda durmuyor". Şimdi, eğer beni reddetmek istiyorsan, cevabım işe yaramıyordu ya da hiçbir şey eklemiyordu. Ama beni reddetseniz, sadece Boost'u sevmeyen büyük bir grup insandan biri olduğumu ve bir şeylerin nasıl çalıştığını çünkü Boost'u seven başka bir grubun parçası olursanız, o zaman gücünüzü kötüye kullanmak. Kalıtımın tersi yönünde #define kullanılmasını önermek için – rabensky

+0

-1, mirasın nesi yanlış olduğunu veya bu kodun makrolarla ilgili genel sorunlardan neden muaf olduğunu. – djechlin