使用Boost Karma生成boost::posix_time::time_duration输出遇阻求助
解决boost::posix_time::duration生成器的符号输出问题
听起来你遇到的问题大概率是符号生成部分输出了无效字符(比如空字符),或者符号生成与duration逻辑不匹配导致流阻塞/未定义行为。我来帮你拆解问题并给出可行的修复方案:
首先排查核心问题点
你提到移除sign_[...]部分后一切正常,那问题肯定出在符号生成的逻辑上:
- 你可能直接把0/1这类数值转成了char(比如
sign = is_negative ? '-' : 0),而0对应的是空字符\0,输出流遇到空字符会直接停止输出; - 符号生成器和duration的正负逻辑脱节,比如生成了'-'但duration却是正数,导致未定义行为;
- 如果用了生成器框架(比如Boost.Test的数据生成器),符号生成器和duration生成器没有同步,导致生成器卡住。
给出正确的实现示例
以下是一个能正常生成带符号boost::posix_time::duration并输出符号的完整生成器,你可以参考调整你的代码:
基础版(独立生成器)
#include <boost/date_time/posix_time/posix_time.hpp> #include <boost/random.hpp> #include <iostream> #include <string> class DurationGenerator { private: // 随机数生成器 boost::random::mt19937 rng_; // 生成0或1,用来决定符号 boost::random::uniform_int_distribution<> sign_dist_{0, 1}; // 生成1到3600秒的随机数 boost::random::uniform_int_distribution<> secs_dist_{1, 3600}; public: DurationGenerator() : rng_(std::random_device{}()) {} // 生成duration,同时输出对应的符号字符串 boost::posix_time::seconds generate(std::string& out_sign) { bool is_negative = sign_dist_(rng_) == 1; int secs = secs_dist_(rng_); // 显式设置符号,避免生成空字符 out_sign = is_negative ? "-" : "+"; // 确保符号和duration正负一致 return is_negative ? -boost::posix_time::seconds(secs) : boost::posix_time::seconds(secs); } }; // 使用示例 int main() { DurationGenerator gen; for (int i = 0; i < 5; ++i) { std::string sign; auto dur = gen.generate(sign); std::cout << sign << dur.total_seconds() << "s\n"; } return 0; }
Boost.Test集成版(如果是用于测试生成器)
如果你是在Boost.Test中使用数据生成器,需要确保符号和duration同步:
#include <boost/test/unit_test.hpp> #include <boost/test/data/test_case.hpp> #include <boost/test/data/monomorphic.hpp> #include <boost/date_time/posix_time/posix_time.hpp> namespace bdata = boost::unit_test::data; BOOST_AUTO_TEST_SUITE(duration_tests) // 组合符号生成器和秒数生成器,确保同步 auto duration_generator = bdata::zip( bdata::make({"+", "-"}), // 符号集合 bdata::random(1, 3600) // 随机秒数 ).transform([](const auto& tuple) { const auto& sign = std::get<0>(tuple); int secs = std::get<1>(tuple); return std::make_pair( sign, sign == "-" ? -boost::posix_time::seconds(secs) : boost::posix_time::seconds(secs) ); }); BOOST_DATA_TEST_CASE(test_duration_generation, duration_generator, data) { const auto& [sign, dur] = data; // 输出符号和duration std::cout << sign << dur.total_seconds() << "s\n"; // 你的测试逻辑... BOOST_CHECK(dur.total_seconds() != 0); } BOOST_AUTO_TEST_SUITE_END()
关键修复步骤
- 替换无效符号生成逻辑:绝对不要用0代替'+',必须显式生成
"+"或"-"字符串/字符; - 确保符号与duration正负一致:生成'-'时,必须返回负的duration,反之亦然;
- 检查输出流状态:如果输出还是卡住,可以在输出后加上
std::cout << std::endl;刷新流,或者检查std::cout.good()判断流是否处于错误状态,若错误则调用std::cout.clear()重置; - 生成器框架同步:如果用了类似Boost.Test的生成器,一定要用
zip把符号和duration生成器绑定,避免异步导致的阻塞。
按照这些步骤调整后,你的符号输出和生成器嵌入问题应该就能解决了。
内容的提问来源于stack exchange,提问作者Addy
相关产品推荐
相关产品推荐

