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

首次使用C++可变参数函数 实现类似Java遍历可变参数功能报错

问题根源

你使用的是C语言旧式可变参数语法,不支持{exprs...}形式的参数包展开操作,同时参数声明为值类型Expr<std::string>,和目标vector存储的Expr<std::string>*指针类型不匹配,因此触发构造函数匹配失败的报错。

C++有两种主流方案实现和Java可变参数等效的遍历逻辑,都可以直接调用参数的accept()方法:


方案1:使用C++可变参数模板(和Java调用方式完全一致)

该方案不需要修改调用逻辑,编译期会自动校验参数类型,性能无额外开销。

类内声明

template<typename... Exprs>
std::string parenthesize(std::string name, Exprs*... exprs);

实现代码

C++17及以上版本(可直接省略vector,用折叠表达式遍历)

template<typename... Exprs>
std::string AstPrinter::parenthesize(std::string name, Exprs*... exprs)
{
    // 可选:编译期校验所有参数都是Expr<std::string>*类型
    static_assert((std::is_same_v<Exprs*, Expr<std::string>*> && ...), "所有参数必须为Expr<std::string>*类型");

    std::string result = "(" + std::move(name);
    // 直接展开参数包逐个调用accept
    ((result += " " + exprs->accept(this)), ...);
    result += ")";
    return result;
}

C++11/14兼容版本(转vector遍历)

#include <vector>
#include <type_traits>

template<typename... Exprs>
std::string AstPrinter::parenthesize(std::string name, Exprs*... exprs)
{
    std::vector<Expr<std::string>*> exprVec = { static_cast<Expr<std::string>*>(exprs)... };
    std::string result = "(" + std::move(name);
    for (auto* expr : exprVec) {
        result += " " + expr->accept(this);
    }
    result += ")";
    return result;
}

调用方式和Java完全一致:parenthesize("func", &expr1, &expr2, &expr3)


方案2:使用std::initializer_list(代码更简洁,无模板开销)

如果所有可变参数都是同类型的Expr<std::string>*,可以用初始化列表实现,不需要写模板代码。

类内声明

#include <initializer_list>

std::string parenthesize(std::string name, std::initializer_list<Expr<std::string>*> exprs);

实现代码

std::string AstPrinter::parenthesize(std::string name, std::initializer_list<Expr<std::string>*> exprs)
{
    std::string result = "(" + std::move(name);
    for (auto* expr : exprs) {
        result += " " + expr->accept(this);
    }
    result += ")";
    return result;
}

调用时仅需要把可变参数用大括号包裹:parenthesize("func", {&expr1, &expr2, &expr3})


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 03:45:00