为什么BOOST_TEST((Iterator == Iterator))需要额外的括号?

时间:2016-06-18 11:30:56

标签: c++ boost

我正在测试binsearch.hpp的二进制搜索实现:

template<typename Iterator, typename T>
Iterator binsearch(Iterator begin, Iterator end, const T &v) {
    if (std::distance(begin, end) == 0) {return end;}

    Iterator save = end;

    while (std::distance(begin, end) > 0) {
        Iterator mid = begin + std::distance(begin, end) / 2;

        if (*mid == v) {
            return mid;
        }

        if (v < *mid) {
            end = mid;
        } else {
            begin = mid + 1;
        }
    }

    return save;
}

使用以下增强驱动单元测试test_binsearch.cpp

#define BOOST_TEST_MODULE test_binsearch
#define BOOST_TEST_DYN_LINK
#include <boost/test/unit_test.hpp>

#include "binsearch.hpp"

BOOST_AUTO_TEST_CASE(empty_0) {
    std::vector<int> xs = {};

    const auto result = binsearch(xs.begin(), xs.end(), 42);

    BOOST_TEST((result == xs.end()));
}

除非我在BOOST_TEST内部用一对额外的括号包围比较,否则我会得到一个非常神秘且长时间的编译错误,它会反复尝试将迭代器转换为char,错误代码和其他一些类型:

  

注意:无法转换't'(类型'const __gnu_cxx :: __ normal_iterator std :: vector&gt;')来键入'char'

    ostr << t;

我得到了一些线索,用额外的括号from here包围我的比较。为什么没有它们就无法编译?

1 个答案:

答案 0 :(得分:3)

来自BOOST_TEST的documentation

  

复杂陈述

     

BOOST_TEST提供增强的报告功能:其他详细信息   日志中提供了失败的操作数和操作,如图所示   以下示例:

     

示例:BOOST_TEST增强报告缩减版

     

<强>代码

#define BOOST_TEST_MODULE boost_test_macro3
#include <boost/test/included/unit_test.hpp>

BOOST_AUTO_TEST_CASE( mytest )
{
  int a = 13, b = 12;
  BOOST_TEST(a - 1 < b);
}

<强>输出

> ./boost_test_macro3 --log_level=all
Running 1 test case...
Entering test module "boost_test_macro3"
test.cpp(12): Entering test case "mytest"
test.cpp(17): error: in "mytest": check a - 1 < b has failed [13 - 1 >= 12]
                                                              ^^^^^^^^^^^^
                                                              !!!  sic !!!
...

注意测试失败报告中强调的片段。对于那些中等程度的C ++,它可能看起来像魔术(新手不会感到惊讶,因为他们不知道语言的局限性;专家知道这个秘密或很容易解决它。)

文档表面上解释了“魔术”如下:

  

BOOST_TEST 解析语句并构造一个表达式。

但是,“魔术”不适用于无法“打印到std::ostream”的类型。因此您的编译错误。幸运的是,“魔术”(基于运算符重载)不能覆盖运算符优先级的C ++规则。通过添加额外的括号对,您可以定义“魔法”无法到达的区域。