【问题标题】:Why does BOOST_TEST((Iterator == Iterator)) require extra parentheses?为什么 BOOST_TEST((Iterator == Iterator)) 需要额外的括号?
【发布时间】:2016-06-18 11:30:55
【问题描述】:

我正在从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 >')转换为类型'char'

    ostr << t;

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

【问题讨论】:

  • 宏中缺少括号?
  • @KarolyHorvath 也许,我对宏不太擅长。然而,像BOOST_TEST(0 == 0) 这样简单的事情不需要额外的括号。
  • 我不太明白他们的源代码中发生了什么,但他们在宏的参数(没有括号)上使用了一些重载的operator&lt;&lt;,并且&lt;&lt; 的优先级高于== 搞砸了起来。
  • 试试std::cout &lt;&lt; result;(或std::cout &lt;&lt; xs.end();),我怀疑你会遇到类似的错误。
  • @jv_ 是的,错误是完全一样的。我们不能在 C++ 中打印迭代器吗?这很奇怪。

标签: c++ boost


【解决方案1】:

来自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++ 运算符优先级规则。通过添加额外的一对括号,您可以定义“魔法”无法到达的领域。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-19
    • 1970-01-01
    • 2014-08-09
    • 2023-03-06
    • 2012-03-13
    • 2014-12-12
    相关资源
    最近更新 更多