2016-02-26 98 views
1

你好,我试图用我的单元测试使用Boost.Test。然而,我的一些函数返回一组元组,返回std::vector< std::tuple< TypeA, TypeB > >在Boost.Test中用BOOST_CHECK_EQUAL_COLLECTION打印std :: tuple的向量

要与BOOST_CHECK_EQUALSBOOST_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 S插入std命名空间中解决这个问题,但这是一个非标准无优雅的解决方案。 那么...我应该如何处理这个问题。 ?

谢谢你的帮助。

+0

您是否尝试过在测试用例之前放置'using namespace tuple_print_aux;'? – ToniBig

回答

0

我相信你的struct print_log_value< std::vector<Type> >前,应申报

template< typename... Types > 
std::ostream& operator<<(std::ostream& s, const std::tuple<Types...> &collection) 

。另外我认为struct print_log_value对于元组的专业化已经足够,因为BOOST_CHECK_EQUAL_COLLECTIONS实际上并没有看到std::vector,而是一个迭代器。