c++ - Boost 预处理器中的迭代限制

标签 c++ boost boost-test boost-preprocessor

我正在使用 Boost::Test 框架为比较函数编写单元测试。对于每个测试用例,我创建了一系列输入元素并将它们成对比较以检查每对比较函数的返回值。我可以手动写出来,也可以写一个函数。在单元测试中编写函数并不好,因为当出现故障时我们获得的有用信息较少。手动写出每个检查会导致非常长的单元测试。所以我决定使用宏来遍历要检查的元素。它看起来像这样:

#define CHECK_NODE_LESS(less, more) do {\
        BOOST_CHECK_EQUAL(compareQueueUnderTest((less), (more)), true); \
        BOOST_CHECK_EQUAL(compareQueueUnderTest((more), (less)), false); \
} while (false)

#define CHECK_NODE_ORDER_ELEMENT(r, elem1, elem2) CHECK_NODE_LESS(elem1, elem2);

#define CHECK_NODE_ORDER_INNER_LOOP(r, list, i, elem) \
        BOOST_PP_SEQ_FOR_EACH(CHECK_NODE_ORDER_ELEMENT, elem, \
                        BOOST_PP_SEQ_REST_N(i, list))

#define CHECK_NODE_ORDER(nodes) \
        BOOST_PP_SEQ_FOR_EACH_I(CHECK_NODE_ORDER_INNER_LOOP, \
                        BOOST_PP_SEQ_TAIL(nodes), nodes)

在部分排序但没有全部排序的测试用例中,我在适当的元素上使用 CHECK_NODE_LESS 宏来检查已排序的元素,它工作正常。在总排序的测试用例中,我使用了 CHECK_NODE_ORDER 宏。例如:

CHECK_NODE_ORDER((node1)(rootNode1)(node2)(rootNode2));

现在这个不编译。我测试的第一件事是注释掉 CHECK_NODE_LESS 宏并运行预处理器以查看生成的内容。这是我所期望的:为正确的元素调用了 CHECK_NODE_LESS。然后我重新引入 CHECK_NODE_LESS 并运行预处理器以查看会发生什么。由于Boost Test中使用了宏,结果真的很难看,但可以看出有些宏没有展开。

最后,我将 CHECK_NODE_LESS 更改为以下内容,现在它可以正常工作了:

#define CHECK_NODE_LESS(less, more) do {\
        BOOST_CHECK(compareQueueUnderTest((less), (more))); \
        BOOST_CHECK(!compareQueueUnderTest((more), (less))); \
} while (false)

我认为问题在于,当我将 BOOST_CHECK_EQUAL 与其他宏一起使用时,Boost 预处理器库中存在一些迭代限制,或者编译器中存在预处理器深度限制(我使用 Clang 3.4)。这个限制是多少?我该如何 boost 它?

最佳答案

天哪。

很有可能没有人从事 Boost.Test 的工作,没有考虑过您要尝试做什么。问题不是编译器限制,而是 BOOST_PP_SEQ_FOR_EACH 不可重入,BOOST_CHECK_EQUAL 使用它。因此,在 BOOST_PP_SEQ_FOR_EACH 中使用 BOOST_CHECK_EQUAL 是不可能的。 BOOST_CHECK 之所以有效,是因为它不使用 BOOST_PP_SEQ_FOR_EACH

我建议采用这种解决方法:

#define CHECK_NODE_ORDER_INNER_LOOP(r, list, i, elem) \
    BOOST_PP_LIST_FOR_EACH(CHECK_NODE_ORDER_ELEMENT, elem, \
                           BOOST_PP_SEQ_TO_LIST(BOOST_PP_SEQ_REST_N(i, list)))

我知道为了嵌套循环的唯一目的将序列转换为列表是相当丑陋的。在我看来,这是我能想到的最不丑陋的方法。

关于c++ - Boost 预处理器中的迭代限制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27123836/

相关文章:

c++ - SDL 结构对象 - 在调用销毁函数后设置为 nullptr?

c++ - 出于某种原因,使用 std::make_pair 需要带有 boost::flat_map 的显式类型

c++ - 了解 boost 执行器示例

c++ - 我应该将单元测试放在单独的库中吗?单独的子目录?

c++ - 使用变量来决定类或命名空间的类型

c++ - 如何在 C++ 中访问对?

c++ - C++中调用成员函数是否需要使用->运算符?

python - Python 2.7 中的 boost 模块?

c++ - Boost数据驱动测试输出: "Assertion occurred in a following context"

c++ - BOOST_AUTO_TEST_SUITE_END() 行出现异常错误