You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用可变参数模板泛化Parser类的ParseMany函数

泛化ParseMany以支持任意数量解析类型(C++20)

可以利用C++20的可变模板参数、lambda模板和折叠表达式,直接写出支持任意数量类型的泛化ParseMany函数,完全替代现有的多个重载版本。以下是改造后的完整代码:

#include <optional>
#include <tuple>
#include <utility>

// 假设Lexer类已定义
class Lexer {};

class Parser {
    Lexer& lexer;

public:
    template<typename ReturnType>
    std::optional<ReturnType> Parse();

    Parser(Lexer& lexer) : lexer(lexer) {}

    // 泛化版本:支持任意数量的待解析类型参数
    template<typename ReturnType, typename... Ts>
    std::optional<ReturnType> ParseMany() {
        // 存储所有解析成功的值
        std::tuple<std::decay_t<Ts>...> parsed_values;
        bool parse_success = true;

        // 借助索引序列逐个解析每个类型
        [&]<std::size_t... Is>(std::index_sequence<Is...>) {
            // 折叠表达式展开解析逻辑,按顺序执行
            ( [&] {
                auto parsed_opt = Parse<std::tuple_element_t<Is, decltype(parsed_values)>>();
                if (!parsed_opt) {
                    parse_success = false;
                    return;
                }
                // 转移值到tuple中,避免拷贝
                std::get<Is>(parsed_values) = std::move(*parsed_opt);
            }(), ... );
        }(std::index_sequence_for<Ts...>{});

        if (!parse_success) {
            return std::nullopt;
        }

        // 将tuple中的值展开构造ReturnType并返回
        return std::apply([](auto&&... args) {
            return ReturnType{ std::forward<decltype(args)>(args)... };
        }, std::move(parsed_values));
    }
};

关键特性说明

  • 可变模板参数:typename... Ts接受任意数量的待解析类型,无需手动编写N个重载。
  • 顺序解析与失败快速返回:严格按照模板参数顺序依次解析,只要有一个类型解析失败,立即标记失败并终止后续解析,和原重载逻辑完全一致。
  • 高效值传递:使用std::move转移解析结果,结合std::forward确保构造ReturnType时的完美转发,避免不必要的拷贝开销。
  • C++20特性依赖:利用带模板参数的lambda(<std::size_t... Is>)和std::index_sequence实现类型参数的遍历展开,VS2022完全支持这些特性。

使用示例

调用方式和原重载版本完全兼容,比如:

// 解析两个类型并构造MyStruct
std::optional<MyStruct> result = parser.ParseMany<MyStruct, IntToken, StringToken>();

内容的提问来源于stack exchange,提问作者girobuz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 16:25:15