从cppcoro迁移至Boost.Cobalt:如何无返回值退出生成器?
迁移cppcoro生成器代码至Boost.Cobalt的优化写法
我正在将基于Lewis Baker的cppcoro库的生成器代码迁移至Boost.Cobalt。cppcoro版本的实现无需返回特殊结束标记即可自然终止生成器,写法简洁优雅,但我当前的Boost.Cobalt版本需要返回"--exit"字符串来判断结束,请问有没有更优的写法?
cppcoro版本实现
#include <cppcoro/generator.hpp> #include <iostream> #include <fstream> #include <string> cppcoro::generator<std::string> read_script_file(std::ifstream& script) { std::string line; while (std::getline(script, line)) { if (line.empty()) { continue; } if (line[0] == '#') { continue; } co_yield line; } } void print_script_file() { std::ifstream ifs("script"); for (const auto line : read_script_file(ifs)) { std::cout << line << "\n"; } }
当前Boost.Cobalt版本实现
#include <boost/cobalt.hpp> #include <fstream> #include <iostream> #include <string> boost::cobalt::generator<std::string> read_script_file(std::ifstream& script) { std::string line; while (std::getline(script, line)) { if (line.empty()) { continue; } if (line[0] == '#') { continue; } co_yield line; } co_return "--exit"; } void print_script_file() { std::ifstream ifs("script"); while (true) { const auto line = co_await read_script_file(ifs); if (line == "--exit") { break; } std::cout << line << "\n"; } }
优化后的Boost.Cobalt写法
Boost.Cobalt的generator支持标准范围遍历,无需手动判断结束标记,写法和cppcoro几乎一致:
#include <boost/cobalt.hpp> #include <fstream> #include <iostream> #include <string> boost::cobalt::generator<std::string> read_script_file(std::ifstream& script) { std::string line; while (std::getline(script, line)) { if (line.empty()) { continue; } if (line[0] == '#') { continue; } co_yield line; } // 无需额外返回结束标记 } void print_script_file() { std::ifstream ifs("script"); // 直接用范围for循环遍历生成器 for (const auto& line : read_script_file(ifs)) { std::cout << line << "\n"; } }
优化说明
Boost.Cobalt的generator实现了标准输入迭代器接口,完全支持范围for循环语法。当生成器执行到函数末尾、没有更多co_yield产出值时,迭代器会自动进入结束状态,循环会自然终止,完全不需要通过返回特殊标记来手动判断结束。
原Boost.Cobalt代码错误地使用co_await直接获取生成器的值,这是对生成器用法的误解。生成器的正确遍历方式和cppcoro一致,使用范围for或手动操作迭代器即可。
内容的提问来源于stack exchange,提问作者josuegomes
相关产品推荐
相关产品推荐

