2011-01-29 8 views
6

Por ejemplo, digamos que tenemos esta clase que se quiere hacer la prueba:¿Cómo pasar contenedores STL como argumentos a BOOST_CHECK_EQUAL?

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

Y la función de prueba está hecha de:

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

STL vector proporciona un operador == libre, pero lo hace no proporciona un operador < <, por lo que este código no se compila. ¿Cómo puedo hacer que esto funcione? ¿Puedo definir mi propio operador < <? ¿Cómo se vería su implementación? crédito adicional a la solución más genérica :)

+0

No existe un 'operador <<', ¿quiere decir operador '' o 'operador <<'? – bdonlan

+0

Supongo que 'get' se supone que es' getSomething'. ¿Qué tiene que ver 'operator <<' con algo? 'BOOST_CHECK_EQUAL' utiliza el operador' == '. – Potatoswatter

+0

@Potato: Sí, pero si la verificación falla, intenta imprimir los dos valores usando 'operator <<'. Por lo tanto, 'BOOST_CHECK_EQUAL' requiere tanto' operator == 'como' operator << '. – Philipp

Respuesta

8

Creo que se debe utilizar BOOST_CHECK_EQUAL_COLLECTIONS, esto pone a prueba cada elemento y también imprime en donde los desajustes son:

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

Gracias. Esto es justo lo que necesitaba. RTFM como duh ... –

1

creo Philipp's answer es la mejor respuesta. Sin embargo, usted puede hacer su propia plantilla de operator<<() que funcione para vectores y otros contenedores estándar si quieres:

// 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); 
} 

Aunque usted puede simplemente cambiar el nombre de output_container() a operator<<() y deshacerse de los operator<<() plantillas per-tipo de contenedor, por lo tanto capturando todos intenta utilizar << en un tipo de clase, esto podría interferir con las plantillas de función operator<<() para otros tipos.

+0

Intenté una solución muy similar antes de publicar mi pregunta, pero no compiló. Copié y pegué su solución y obtengo el mismo error: error C2679: binario '<<': no ​​se encontró operador que tome un operando de la derecha del tipo 'const std :: vector <_Ty>' (o no hay una conversión aceptable) 1> con 1> [ 1> _Ty = uint8_t 1>] –

+0

@zr: Parece que la búsqueda de nombre está fallando. ¿Estás seguro de que todas estas plantillas están definidas antes de usarse? –

+0

@zr: También parece que en realidad estás usando un 'vector ', no 'vector ' como se anuncia, ¿es así? De lo contrario, estoy confundido. –

0

Estaba buscando algo similar, una forma de personalizar la cadena de salida para imprimir enteros en hexadecimal. Inyectar un operador en el espacio de nombres std funcionaría, pero cada BOOST_CHECK en mi prueba se imprimiría en hexadecimal.

Así que inyecté algunos operadores personalizados en el espacio de nombres de impulso que pude controlar con algunos bools globales.

Ver mi respuesta aquí boost-check-fails-to-compile-operator-for-custom-types.

Cuestiones relacionadas