您好我正在尝试使用Boost.Test
进行单元测试。但是我的一些函数返回std::vector< std::tuple< TypeA, TypeB > >
中的元组集合。
要使用BOOST_CHECK_EQUALS
和BOOST_CHECK_EQUAL_COLLECTION
,我专门boost::test_tools::print_log_value
打印好的元组和向量,the answer to this question解释。我还为元组提供operator<<
,以便我的向量可以在打印整个向量时使用它。为了清洁,这个操作符位于空白名称空间中。
但编译失败,因为boost::test_tools::print_log_value
<std::vector<std::tuple<...>>>
的实现无法找到元组的operator<<
。
这是一个最小的代码,对不起,已经非常详细了。
#define BOOST_TEST_MODULE my_test
#include <boost/test/included/unit_test.hpp>
#include <tuple>
#include <vector>
/////////////////
// std::vector //
/////////////////
// boost printing method
namespace boost {
namespace test_tools {
template< typename Type >
struct print_log_value< std::vector< Type > > {
void operator()( std::ostream& s, const std::vector< Type > &collection ) {
const int size = collection.size();
if( size == 0 ) {
s << "[]";
}
else {
s << "[ ";
for( int i =0; i <= size-2; ++i ) {
s << collection[i] << ", ";
}
s << collection[size-1] << " ]";
}
return s;
}
};
} //namespace test_tools
} //namespace boost
////////////////
// std::tuple //
////////////////
// recursive calls for printing
namespace tuple_print_aux{
template< int I, int J, typename... Types >
struct recursive_printer {
static void print( std::ostream& s, const std::tuple<Types...> &collection ) {
s << std::get< I >( collection ) << ", ";
recursive_printer< I+1, J-1, Types... >::print( s, collection );
}
};
template< int I, typename... Types >
struct recursive_printer< I, 1, Types... > {
static void print( std::ostream& s, const std::tuple<Types...> &collection ) {
s << std::get< I >( collection );
}
};
template< typename... Types >
void recursive_print( std::ostream& s, const std::tuple<Types...> &collection ) {
recursive_printer< 0, sizeof...(Types), Types... >::print( s, collection );
}
}
// output stream operator
template< typename... Types >
std::ostream& operator<<( std::ostream& s, const std::tuple<Types...> &collection ) {
s << "( ";
tuple_print_aux::recursive_print< Types... >( s, collection );
s << " )";
return s;
}
// boost printing method
namespace boost {
namespace test_tools {
template< typename... Types >
struct print_log_value< std::tuple< Types... > > {
void operator()( std::ostream& s, const std::tuple<Types...> &collection ) {
s << "( ";
tuple_print_aux::recursive_print< Types... >( s, collection );
s << " )";
}
};
} //namespace test_tools
} //namespace boost
BOOST_AUTO_TEST_CASE(my_test_case) {
//builds successfully
BOOST_CHECK_EQUAL( std::make_tuple(1,"a"), std::make_tuple(1,"a") );
//builds successfully
std::vector< int > v( 2, 3 ), w( 2, 7 );
BOOST_CHECK_EQUAL_COLLECTIONS( v.begin(), v.end(), w.begin(), w.end() );
//fails to build
std::vector< std::tuple<int,int> > a( 1, std::make_tuple(1,3) ), b( 1, std::make_tuple(2,2) );
BOOST_CHECK_EQUAL_COLLECTIONS( a.begin(), a.end(), b.begin(), b.end() );
};
当然,将operator<<
std::tuple
放入std
命名空间可以解决问题,但这是一个非标准的非优雅解决方案。
那么......我该如何处理这个问题呢。 ?
感谢您的帮助。
答案 0 :(得分:0)
我相信你应该宣布
template< typename... Types >
std::ostream& operator<<( std::ostream& s, const std::tuple<Types...> &collection )
在struct print_log_value< std::vector< Type > >
之前。另外我认为struct print_log_value
对元组的专业化就足够了,因为BOOST_CHECK_EQUAL_COLLECTIONS
实际上看不到std::vector
,而是它上面的迭代器。