2011-01-29 11 views
6

Per esempio, dire che abbiamo questa classe che vogliamo testare:Come passare container STL come argomenti a BOOST_CHECK_EQUAL?

struct TestMe { 
    vector<int> getSomething(); 
} 

E la funzione di test è costituito da:

... 
vector<int> Expected; 
TestMe TM; 
... 
Result = TM.getSomething(); 
BOOST_CHECK_EQUAL(Result, Expected); 
... 

STL vettore fornisce un operatore == libero, ma lo fa non fornire un operatore < <, quindi questo codice non viene compilato. Come posso farlo funzionare? Posso definire il mio operatore < <? Come sarebbe la sua implementazione? di credito in più per la soluzione più generica :)

+0

Non esiste un 'operatore <<', vuoi dire 'operatore <' o 'operatore <<'? – bdonlan

+0

Suppongo che 'get' debba essere' getSomething'. Cosa c'entra l'operatore << con qualcosa? 'BOOST_CHECK_EQUAL' usa l'operatore' == '. – Potatoswatter

+0

@Potato: Sì, ma se il controllo fallisce, prova a stampare i due valori usando 'operator <<'. Quindi 'BOOST_CHECK_EQUAL' richiede sia' operator ==' che 'operator <<'. – Philipp

risposta

8

Credo che si dovrebbe usare BOOST_CHECK_EQUAL_COLLECTIONS, questo test ogni elemento e anche stampa in cui le discordanze sono:

BOOST_CHECK_EQUAL_COLLECTIONS(Result.begin(), Result.end(), Expected.begin(), Expected.end()); 
+0

Grazie. Questo è proprio quello di cui avevo bisogno. RTFM come duh ... –

1

penso Philipp's answer è la risposta migliore. Tuttavia è possibile fare il vostro proprio su modelli operator<<() che lavorerà per vettori e altri contenitori standard, se si desidera:

// Will write out any container that has begin(), end() and a const_iterator type 
template <typename C> 
std::ostream& output_container(std::ostream& os, C const& c) { 
    for (typename C::const_iterator i = c.begin(); i != c.end(); ++i) { 
     if (i != c.begin()) os << ", "; 
     os << *i; 
    } 

    return os; 
} 

// Overload operators for each container type that forward to output_container() 
template <typename T> 
std::ostream& operator<<(std::ostream& os, vector<T> const& c) { 
    return output_container(os, c); 
} 

template <typename T> 
std::ostream& operator<<(std::ostream& os, list<T> const& c) { 
    return output_container(os, c); 
} 

Anche se si potrebbe semplicemente rinominare output_container()-operator<<() e sbarazzarsi del per-contenitore-tipo operator<<() modelli, in tal modo rilevando tutti i tentativi di utilizzare << in un tipo di classe, questo potrebbe interferire con i modelli di funzione operator<<() per altri tipi.

+0

Ho provato una soluzione molto simile prima di postare la mia domanda, ma non è stata compilata. Ho copiato la tua soluzione e ho ottenuto lo stesso errore: errore C2679: binario '<<': nessun operatore trovato che prende un operando a destra di tipo 'const std :: vector <_Ty>' (o non vi è alcuna conversione accettabile) 1> con 1> [ 1> _Ty = uint8_t 1>] –

+0

@zr: Sembra che la ricerca del nome stia fallendo. Sei sicuro che tutti questi modelli siano definiti prima che vengano utilizzati? –

+0

@zr: Sembra che tu stia effettivamente usando un 'vector ', non 'vector ' come pubblicizzato - è così? Altrimenti sono confuso. –

0

Stavo cercando qualcosa di simile, un modo per personalizzare la stringa di output per stampare interi in esadecimale. L'iniezione di un operatore nello spazio dei nomi std funzionerebbe, ma ogni BOOST_CHECK nel mio test verrebbe stampato in esadecimale.

Così ho iniettato alcuni operatori personalizzati nello spazio dei nomi boost che potevo controllare con alcuni bool globali.

Vedere la mia risposta qui boost-check-fails-to-compile-operator-for-custom-types.

Problemi correlati