2016-02-26 39 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,而是一個迭代器。