Boost.Test在测试套件中包含STL代码时编译错误求助
问题:Boost.Test测试套件包裹标准库头文件导致编译错误
环境
- Windows 10
- MSYS2环境,包含:
- g++ 12.2.0
- Boost.Test 1.81.0
测试代码(test.cpp)
// test.cpp #define BOOST_TEST_MAIN #define BOOST_TEST_MODULE a_nice_testing_attempt #include <boost/test/included/unit_test.hpp> // this is available BOOST_AUTO_TEST_SUITE(MyNiceTestSuite) // (*) #include <chrono> // actually I want to test much more, but I narrowed // the problem down to this minimal snippet BOOST_AUTO_TEST_SUITE_END() // (*)
编译命令
g++ test.cpp -o test.exe
编译错误信息(部分)
前期错误
In file included from C:/msys64/mingw64/include/c++/12.2.0/bits/chrono.h:37, from C:/msys64/mingw64/include/c++/12.2.0/chrono:39, from test_main.cpp:17: C:/msys64/mingw64/include/c++/12.2.0/ratio:58:24: error: expected template-name before '<' token 58 | : integral_constant<intmax_t, (_Pn < 0)? -1 : 1> | ^ C:/msys64/mingw64/include/c++/12.2.0/ratio:58:24: error: expected '{' before '<' token C:/msys64/mingw64/include/c++/12.2.0/ratio:63:24: error: expected template-name before '<' token 63 | : integral_constant<intmax_t, _Pn * __static_sign<_Pn>::value> | ^
后期错误
C:/msys64/mingw64/include/c++/12.2.0/bits/chrono.h:1371:47: required from 'static MyNiceTestSuite: :std::chrono::time_point<MyNiceTestSuite::std::filesystem::__file_clock, _Dur> MyNiceTestSuite::std: :filesystem::__file_clock::_S_from_sys(const MyNiceTestSuite::std::chrono::time_point<MyNiceTestSuit e::std::chrono::_V2::system_clock, _Dur2>&) [with _Dur = MyNiceTestSuite::std::chrono::duration<long long int, MyNiceTestSuite::std::ratio<1, 1000000000> >]' C:/msys64/mingw64/include/c++/12.2.0/bits/chrono.h:1338:27: required from here C:/msys64/mingw64/include/c++/12.2.0/bits/chrono.h:1020:16: error: cannot convert '__time_point' {ak a 'MyNiceTestSuite::std::chrono::time_point<MyNiceTestSuite::std::filesystem::__file_clock, int>'} t o 'int' in return 1020 | return __time_point(__lhs.time_since_epoch() -__rhs); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | __time_point {aka MyNiceTestSuite::std::chrono::time_point<MyNiceTestSuite::s td::filesystem::__file_clock, int>}
问题现象
移除标记为(*)的BOOST_AUTO_TEST_SUITE和BOOST_AUTO_TEST_SUITE_END()代码后,编译可正常通过。
原因分析
BOOST_AUTO_TEST_SUITE会将后续代码包裹到同名的C++命名空间中。当在这个命名空间内包含<chrono>等标准库头文件时,标准库的内部实现代码会被错误地放入该自定义命名空间,导致标准库的核心模板(如std::integral_constant)无法被正确识别,进而引发大量编译错误。
从错误信息中可以看到,标准库类型被解析为MyNiceTestSuite::std::chrono::...,这说明标准库代码被意外拉入了测试套件的命名空间,破坏了标准库原本的命名空间结构。
解决方法
所有标准库头文件必须在BOOST_AUTO_TEST_SUITE之前包含,避免标准库代码被混入自定义测试命名空间:
修改后的代码:
// test.cpp #define BOOST_TEST_MAIN #define BOOST_TEST_MODULE a_nice_testing_attempt #include <boost/test/included/unit_test.hpp> #include <chrono> // 移到测试套件外面 BOOST_AUTO_TEST_SUITE(MyNiceTestSuite) // 测试代码放在这里,需要用到chrono时直接使用std::chrono即可 BOOST_AUTO_TEST_SUITE_END()
若需在测试套件内使用标准库类型,只需确保头文件在命名空间外包含,在命名空间内直接使用std::前缀的类型即可。
内容的提问来源于stack exchange,提问作者deponovo
相关产品推荐
相关产品推荐

