2012-09-20 11 views
8

Come parte di un team di sviluppatori, volevo garantire che un insieme di funzioni (e operatori) siano implementati sugli iteratori personalizzati che pubblichiamo. L'utilizzo dei tipi di iteratore STL come tipi di base aiuta, tuttavia a causa di alcuni motivi (fuori dal mio controllo) decidiamo di non applicare la compatibilità STL. Gli iteratori sono consumati dalla stessa squadra e da persone in tutta la società.static_assert per garantire il contratto di progettazione

Volevo progettare una classe template che consumasse il tipo iteratore e testasse il contratto di progettazione.

Ad esempio, mi aspetto che un iteratore realizzi un operatore ++, operatore-- e dichiari anche i typedef richiesti.

1> È possibile implementare una tale classe di modello che applica il contratto di progettazione? probabilmente usando static_assert?

2> Se sì, è un buon design?

di riferimento: custom iterator

+1

http: //www.boost.org/doc/libs/1_48_0/libs/type_traits/doc/html/boost_typetraits/category/value_traits/operators.html forse? – BoBTFish

+1

La [bella stampante] (http://stackoverflow.com/q/4850473/596781) ha una classe di tratto C++ 11 per verificare se un tipo ha tipi di iteratore e funzioni 'begin' /' end' che restituiscono quell'iteratore genere. –

+0

@Kerrek Grazie per l'esempio. Ho salvato diverse ore uomo. :) – Ram

risposta

10

È possibile implementare una tale classe di modello che applica il contratto di progettazione? probabilmente usando static_assert?

Per verificare se esiste metodo specifico (molto simile a this example):

struct Hello 
{ 
}; 

struct Generic { 
    int operator++() 
    { 
     return 5; 
    } 
}; 


// SFINAE test 
template <typename T> 
class has_operator_plusplus 
{ 
    typedef char one; 
    typedef long two; 

    template <typename C> static one test(decltype(&C::operator++)) ; 
    template <typename C> static two test(...); 

public: 
    enum { value = sizeof(test<T>(0)) == sizeof(char) }; 
}; 


int main(int argc, char *argv[]) 
{ 
    // the first check breaks the build 
    //static_assert(has_operator_plusplus<Hello>::value, "has no operator"); 
    static_assert(has_operator_plusplus<Generic>::value, "has no operator"); 
} 

è questo un buon progetto?

Sì, perché rompendo la costruzione, l'errore viene preso molto veloce, e l'utente della classe hanno Indifferente di leggere la documentazione (la maggior parte delle persone di solito saltare quella parte della programmazione)

+0

Posso chiedere cosa significa test (...)? Non ho abbastanza la sintassi di tre punti lì. – DawidPi

+0

@DawidPi Vedi [funzione variadic] (http://en.cppreference.com/w/cpp/utility/variadic) –

2

Sì, è possibile implementare una classe template. È possibile utilizzare SFINAE per verificare la presenza di vari membri e, se non sono corretti, static_assert. Anche se non sono sicuro del perché vorresti definire typedef in un mondo C++ 11.

È sempre una buona idea eseguire controlli aggiuntivi sul codice.

Problemi correlati