c++ boost boost-test

c++ - BOOST_CHECK_EQUAL con par<int, int> y operador personalizado<<



boost-test (3)

Intente ubicar al operador en el espacio de nombre estándar :

namespace std { ostream& operator<<(ostream& s, const pair<int,int>& p) { s << ''<'' << p.first << '','' << p.second << ''>''; return s; } }

Actualización: quizás esta es la razón por la cual la ADL falla (al menos en llvm):

Al igual que antes, la búsqueda no calificada no encontró ninguna declaración con el operator<< nombre operator<< . A diferencia de antes, los tipos de argumentos contienen tipos de clase: uno de ellos es una instancia del tipo de plantilla de clase std::basic_ostream , y el otro es el tipo ns::Data que hemos declarado anteriormente. Por lo tanto, ADL buscará en los espacios de nombres std y ns para un operator<< . Dado que uno de los tipos de argumentos aún era dependiente durante la definición de la plantilla, ADL no se realiza hasta que la plantilla se crea una instancia durante el uso, lo que significa que el operator<< que queremos que encuentre ya ha sido declarado. Desafortunadamente, fue declarado en el espacio de nombres global, ¡no en ninguno de los espacios de nombres en los que se verá ADL!

Al intentar hacer un BOOST_CHECK_EQUAL (par, par), gcc no encuentra el operador de la ruta para el par, a pesar de declararlo. Lo curioso es que std :: out encuentra al operador.

ostream& operator<<(ostream& s, const pair<int,int>& p) { s << ''<'' << p.first << '','' << p.second << ''>''; return s; } BOOST_AUTO_TEST_CASE(works) { pair<int,int> expected(5, 5); pair<int,int> actual (5, 5); std::cout << expected << std::endl; std::cout << actual << std::endl; BOOST_CHECK(actual == expected); } BOOST_AUTO_TEST_CASE(no_work) { pair<int,int> expected(5, 5); pair<int,int> actual (5, 5); BOOST_CHECK_EQUAL(actual, expected); }

Esto no compila con el error:

... instantiated from here ../boost-atp/release/include/boost/test/test_tools.hpp:326:9: error: no match for ‘operator<<’ in ‘ostr << t’


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 podía controlar con algunos bools globales.

Vea mi respuesta aquí boost-check-failed-to-compile-operator-for-custom-types .


Poner operator<< en std como la respuesta de Remus es un comportamiento indefinido en el borrador de C ++ 14 (sección N4296: 17.6.4.2.1). Boost proporciona un gancho ( utilizado por esta respuesta ) y puede escribir:

namespace boost { namespace test_tools { template<typename T,typename U> struct print_log_value<std::pair<T, U> > { void operator()(std::ostream& os, std::pair<T, U> const& pr) { os << "<" << std::get<0>(pr) << "," << std::get<1>(pr) << ">"; } }; } }

print_log_value es una plantilla así que si no está declarando un valor de plantilla como pair<T,U> , tendrá que escribir algo como:

template<> struct print_log_value<MyType>{ /* implementation here*/ };

Editar

Si está utilizando boost 1.59 o posterior, necesita usar namespace boost::test_tools::tt_detail en boost::test_tools::tt_detail lugar. Es decir, el código debe comenzar:

namespace boost { namespace test_tools { namespace tt_detail {