Boost.Cobalt:如何退出生成器而不返回值

问题描述 投票:0回答:1

我正在将使用 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

c++ boost
1个回答
0
投票

回答我自己的问题。 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;
}
© www.soinside.com 2019 - 2024. All rights reserved.