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

exprtk函数合成成功后符号表中缺失函数名问题排查

问题根源

你遇到的问题核心在于:function_compositor实例是add_function函数内的局部变量,当该函数执行完毕后,这个局部的compositor会被销毁。而exprtk的设计中,function_compositor会管理它添加到符号表中的所有合成函数,一旦它被销毁,这些函数会被自动从符号表中移除,所以后续编译表达式时,符号表中已经没有incrementor函数了。

解决方法

你可以通过延长function_compositor的生命周期来解决这个问题,以下是两种常用的可行方式:

方式一:让compositor生命周期与符号表绑定

修改主函数,将compositor定义为主函数内的变量,再把它的引用传入add_function,确保它的生命周期覆盖符号表的整个使用周期:

// 修改add_function,接收compositor的引用
void add_function(exprtk::symbol_table<double>& symtab, exprtk::function_compositor<double>& compositor) {
    using function_t = typename exprtk::function_compositor<double>::function;

    const bool res = compositor.add(
        function_t("incrementor")
        .var("x")
        .expression("x + 1;"));

    if (!res) {
        printf("comp err!");
    }
}

// 主函数逻辑
int main() {
    using symbol_table_t = exprtk::symbol_table<double>;
    using expression_t   = exprtk::expression<double>;
    using parser_t       = exprtk::parser<double>;
    using compositor_t   = exprtk::function_compositor<double>;

    double x = 123.0;

    symbol_table_t symbol_table;
    expression_t   expression;
    parser_t       parser;
    compositor_t compositor(symbol_table); // 生命周期与符号表一致

    symbol_table.add_variable("x", x);
    add_function(symbol_table, compositor); // 传入compositor引用

    expression.register_symbol_table(symbol_table);

    const std::string program = "incrementor(x)";

    if (!parser.compile(program,expression)) {
        printf("err: %s\n",parser.error().c_str());
        return 1;
    }

    double result = expression.value();
    printf("Result: %f\n", result);
    return 0;
}

方式二:将compositor声明为静态变量

在add_function内把compositor定义为静态变量,这样它的生命周期会延续到整个程序结束,不会随函数返回而销毁:

void add_function(exprtk::symbol_table<double>& symtab) {
    using compositor_t = exprtk::function_compositor<double>;
    using function_t   = typename compositor_t::function;

    static compositor_t compositor(symtab); // 静态变量,生命周期覆盖整个程序运行期

    const bool res = compositor.add(
        function_t("incrementor")
        .var("x")
        .expression("x + 1;"));

    if (!res) {
        printf("comp err!");
    }
}
验证说明

修改后重新编译运行,调试时再检查符号表,incrementor函数会保持存在,parser.compile能成功执行,最终表达式计算结果应为124.0。

内容的提问来源于stack exchange,提问作者Samuel D.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 22:40:04