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

如何从Exprtk表达式中获取返回的字符串结果?

如何从Exprtk表达式中获取返回的字符串结果?

Exprtk中直接调用expression.value()仅能获取数值结果,对于返回字符串的表达式(比如示例中的if(1>0,'One','Two'))会得到NaN。调试时发现表达式的control_block_私有属性里的string value_已存储正确的字符串结果,但无法直接访问。目前已知可通过return[]语句或显式定义字符串变量来获取结果,但希望能有更便捷的方式,以下是可行解决方案:

示例问题代码

#include "exprtk.hpp"

int main()
{
   typedef exprtk::symbol_table<double> symbol_table_t;
   typedef exprtk::expression<double>   expression_t;
   typedef exprtk::parser<double>       parser_t;

   const std::string expression_string =
                     //"if (1 > 0) {'One';} else {'Two';}";
                        "if (1 > 0,'One','Two')";

   expression_t expression;
   parser_t parser;

   if (parser.compile(expression_string, expression))
   {
       double result = expression.value();
       // 如何在此处获取字符串结果?
   }
   return 0;
}

解决方案

方法1:绑定显式字符串变量(官方推荐)

在符号表中定义字符串变量,让表达式将结果赋值给该变量,这是最稳妥的官方支持方式:

#include "exprtk.hpp"

int main()
{
   typedef exprtk::symbol_table<double> symbol_table_t;
   typedef exprtk::expression<double>   expression_t;
   typedef exprtk::parser<double>       parser_t;

   std::string result_str;

   symbol_table_t symbol_table;
   symbol_table.add_stringvar("str_result", result_str);

   const std::string expression_string =
                     "str_result := if (1 > 0,'One','Two');";

   expression_t expression;
   expression.register_symbol_table(symbol_table);

   parser_t parser;

   if (parser.compile(expression_string, expression))
   {
       expression.value(); // 执行表达式,结果自动写入result_str
       printf("结果:%s\n", result_str.c_str());
   }
   return 0;
}

方法2:利用return[]语句捕获字符串

通过表达式中的return[]返回字符串,再调用表达式的return_values()方法获取结果(需确保使用的Exprtk版本支持该特性):

#include "exprtk.hpp"

int main()
{
   typedef exprtk::symbol_table<double> symbol_table_t;
   typedef exprtk::expression<double>   expression_t;
   typedef exprtk::parser<double>       parser_t;

   const std::string expression_string =
                     "return[if (1 > 0,'One','Two')];";

   expression_t expression;
   parser_t parser;

   if (parser.compile(expression_string, expression))
   {
       expression.value(); // 执行表达式
       const auto& return_vals = expression.return_values();
       if (!return_vals.empty() && return_vals[0].is_string())
       {
           std::string result_str = return_vals[0].string_value();
           printf("结果:%s\n", result_str.c_str());
       }
   }
   return 0;
}

方法3:直接访问私有成员(不推荐用于生产环境)

若需临时调试或特殊场景,可通过类型转换绕过私有成员访问限制,但这属于未定义行为,依赖Exprtk内部实现,版本更新后可能失效:

// 仅用于调试,生产环境禁止使用
#include "exprtk.hpp"
#include <cstddef>

// 需与Exprtk源码中control_block的结构完全匹配,避免内存偏移错误
struct FakeControlBlock {
    std::string value_;
    // 补充Exprtk control_block中的其他成员变量
};

int main()
{
   typedef exprtk::symbol_table<double> symbol_table_t;
   typedef exprtk::expression<double>   expression_t;
   typedef exprtk::parser<double>       parser_t;

   const std::string expression_string =
                     "if (1 > 0,'One','Two')";

   expression_t expression;
   parser_t parser;

   if (parser.compile(expression_string, expression))
   {
       expression.value();
       // 强制转换获取control_block_,依赖内部内存布局
       FakeControlBlock* fake_cb = reinterpret_cast<FakeControlBlock*>(&expression.control_block_);
       printf("结果:%s\n", fake_cb->value_.c_str());
   }
   return 0;
}

说明

Exprtk核心设计面向数值计算,字符串处理属于附加特性,官方推荐使用前两种规范方式获取字符串结果。直接访问私有成员会破坏封装性,且无法保证跨版本兼容性,不建议在生产环境使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 13:00:24