我正在将使用 Lewis Baker 的 cppcoro 库的代码转换为使用 Boost.Cobalt
#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";
}
}
cppcoro 版本更加优雅,因为它不需要返回“--exit”字符串来完成 发电机。 有没有更好的方法来编写Boost.Cobalt版本?
[1] cppcoro - https://github.com/lewissbaker/cppcoro
[2] Boost.Cobalt - https://github.com/boostorg/cobalt
回答我自己的问题。 Boost.Cobalt 作者提供了回复[1]。
总之,从该协程不返回任何值是 UB(未定义行为)。
这是最终的完整示例:
#include <boost/cobalt.hpp>
#include <boost/cobalt/main.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 {};
}
boost::cobalt::main co_main(int argc, char *argv[])
{
try {
std::ifstream script("script");
if (!script) {
std::cerr << "ERR: failed to open " << argv[1] << "\n";
co_return 1;
}
auto g = read_script_file(script);
while (g) {
const auto line = co_await g;
if (line.empty()) {
break;
}
std::cout << "<" << line << ">\n";
}
}
catch (const std::exception& e) {
std::cout << "Exception: " << e.what() << "\n";
}
co_return 0;
}