5

Cosa è preferibile (se presente)?Barton-Nackman vs std :: enable_if

Variante A (Barton-Nackman):

template<class T> 
struct equal_comparable { 
    friend bool operator == (const T & t1, const T & t2) { 
     return t1.equalTo (t2); 
    } 
}; 

class MyClass : private equal_comparable<MyClass> { 
    bool equalTo (const MyClass & other) //... 
}; 

Variante B (std :: enable_if):

struct MyClass { 
    static const bool use_my_equal = true; 
    bool equalTo (const MyClass & other) //... 
}; 

template<class T> 
typename std::enable_if< 
    T::use_my_equal, 
    bool 
>::type 
operator == (const T & t1, const T & t2) { return t1.equalTo (t2); } 
+0

Personalmente preferisco il primo. 'equal_comparable' può essere inserito in uno spazio dei nomi adatto, ma chissà che cosa il membro' use_my_equal' è usato per qualche tipo 'T' di cui non hai mai sentito parlare. Ovviamente questo problema si applica ad altri usi simili di 'enable_if' - solo perché un nome dipendente si risolve non * necessariamente * significa che il nome è usato per quello che pensi che significhi, se lo stai estraendo da uno spazio dei nomi non controllare Potresti invece usare un carattere tipografico. –

+0

Perché utilizzare un modello? Perché non solo 'bool operator == (const MyClass &,/* etc * /) ;?' – GManNickG

+0

@GManNickG: Credo che lo scopo del trucco sia di ridurre il numero di piastre richieste per classe che è paragonabile alla parità. –

risposta

4

preferisco usare Boost.Operators citato da @SteveJessop nei commenti, che formalizza e automatizza il tuo primo approccio. Si occupano anche dell'ottimizzazione della base vuota se ti occorrono più insiemi di operatori (e quindi avrebbero bisogno di ereditarietà multipla). Non sono tanto i risparmi nella digitazione, ma anche la documentazione del codice/il valore dell'applicazione, dal momento che queste classi di basi sono proprio nella parte anteriore dell'interfaccia di classe. In questo senso, è un modo primitivo di concetti.