BOOST_CHECK_EQUAL与pair <int,int =“”>和自定义运算符&lt;&lt; </int,>

时间:2012-06-11 07:41:22

标签: c++ boost boost-test

尝试执行BOOST_CHECK_EQUAL(对,对)时, gcc没有找到对的流操作符,尽管声明它。 有趣的是std :: out找到了运算符。

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);
}

这不会编译错误:

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

3 个答案:

答案 0 :(得分:10)

operator<<放在std中,如Remus's answer,这是C ++ 14草案中的未定义行为(N4296部分:17.6.4.2.1)。 Boost提供了一个钩子(used by this answer),你可以写:

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是一个模板,因此,如果您没有声明像pair<T,U>这样的模板化值,则需要编写类似的内容:

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

修改

如果您使用的是boost 1.59或更高版本,则需要使用名称空间boost::test_tools::tt_detail。也就是说,代码需要启动:

namespace boost
{
    namespace test_tools
    {
        namespace tt_detail
        {

答案 1 :(得分:9)

尝试放置operator itself in the std namespace

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

更新:也许这就是为什么ADL fails(至少在llvm上):

  

就像之前一样,不合格的查找没有找到任何声明   名称operator<<。与以前不同,参数类型都包含   类类型:其中一个是类模板类型的实例   std::basic_ostream,另一个是我们的类型ns::Data   如上所述。因此,ADL将查找名称空间stdns   对于operator<<。由于其中一个参数类型仍然依赖   在模板定义期间,ADL在模板完成之前不会完成   在使用期间实例化,这意味着我们希望它operator<<   找到已经宣布。不幸的是,它在宣布   全局命名空间,不在ADL看起来的任何一个命名空间中   在!

答案 2 :(得分:0)

我正在寻找类似的东西,一种自定义输出字符串以十六进制打印整数的方法。将操作符注入std命名空间会起作用,但我测试中的每个BOOST_CHECK都将以十六进制格式打印。

所以我在boost名称空间中注入了一些自定义运算符,我可以用一些全局bool来控制它。

请在此处查看我的回答boost-check-fails-to-compile-operator-for-custom-types