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<<
nombreoperator<<
. A diferencia de antes, los tipos de argumentos contienen tipos de clase: uno de ellos es una instancia del tipo de plantilla de clasestd::basic_ostream
, y el otro es el tipons::Data
que hemos declarado anteriormente. Por lo tanto, ADL buscará en los espacios de nombresstd
yns
para unoperator<<
. 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 eloperator<<
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
{