3

我似乎无法从 exprTk 获得矢量输出。我认为它应该相对简单,但在手册中我只能找到如何输入矢量而不是如何输出矢量。

我目前拥有的是以下内容:

typedef double T; // numeric type (float, double, mpfr etc...)
typedef exprtk::symbol_table<T> symbol_table_t;
typedef exprtk::expression<T>     expression_t;
typedef exprtk::parser<T>             parser_t;

std::string expression_string = "var z[2] := { x, y };";

T x = T(5.3);
T y = T(2.3);
std::vector<T> z;

symbol_table_t symbol_table;
symbol_table.add_variable("x", x);
symbol_table.add_variable("y", y);
symbol_table.add_vector("z", z);

expression_t expression;
expression.register_symbol_table(symbol_table);

//Check if expression is valid
parser_t parser;
if (!parser.compile(expression_string, expression))
{
    printf("Compilation error...\n");
    return;
}

T result = expression.value();
std::cout << result << std::endl;     \\returns: 5.3 as expected the first element of vector z.
std::cout << z[0] << std::endl;       \\Crashes the program 

我想要的输出只是向量z。我该怎么做,或者我做错了什么?

4

2 回答 2

3

根据自述文件的第 20 节 - 表达式返回值,只需使用 return 语句,即可立即退出返回任意数量的任意类型变量的表达式。

文档中提供的示例如下:

std::string expression_string =
   " if (x < y)                                   "
   "   return [x + 1,'return-call 1'];            "
   " else if (x > y)                              "
   "   return [y / 2, y + 1, 'return-call 2'];    "
   " else if (equal(x,y))                         "
   "   x + y;                                     "
   " return [x, y, x + y, x - y, 'return-call 3'] ";

typedef exprtk::symbol_table<double> symbol_table_t;
typedef exprtk::expression<double>     expression_t;
typedef exprtk::parser<double>             parser_t;

symbol_table_t symbol_table;
expression_t   expression;
parser_t       parser;

double x = 0;
double y = 0;

symbol_table.add_variable("x",x);
symbol_table.add_variable("y",y);

expression.register_symbol_table(symbol_table);

parser.compile(expression_string,expression);

T result = expression.value();

if (expression.results().count())
{
   typedef exprtk::results_context<T> results_context_t;
   typedef typename results_context_t::type_store_t type_t;
   typedef typename type_t::scalar_view scalar_t;
   typedef typename type_t::vector_view vector_t;
   typedef typename type_t::string_view string_t;

   const results_context_t& results = expression.results();

   for (std::size_t i = 0; i < results.count(); ++i)
   {
      type_t t = results[i];

      switch (t.type)
      {
         case type_t::e_scalar : ...
                                 break;

         case type_t::e_vector : ...
                                 break;

         case type_t::e_string : ...
                                 break;

         default               : continue;
      }
}

注意1: 您的表达式将变为:

var z[2] := { x, y }; return [z];

注意2: 为了获得“单行”方法,您可以编写一个简单的自由函数,在条件之后包装样板代码并从列表中提取您选择的向量(给定向量类型的第 i 个结果)results .

template <typename T>
bool get_vector(const std::size_t index, 
                const results_context_t& results,
                std::vector<T>& v)
{
   ...
}
于 2020-05-31T00:00:45.007 回答
1

我找到了一种可行的方法,但希望有一种更简单的“单行”方法

std::string expression_string = "var w[2] := { x, y }; z := w";

这将创建一个表达式局部向量w([SECTION 13 - VARIABLE, VECTOR & STRING DEFINITION]),然后将值分配给z

正如@NathanOliver 提到的,std::vector<T> z(2);也需要


"var z[2] := { x, y };"不起作用z,因为由于使用了var语句,这是对变量的非法重新定义。

请注意,这"z := {x, y}"也不起作用,因为这似乎不是向量的有效赋值表达式


输出(启用调试):

prev[var] --> curr[var]
prev[var] --> curr[w]
prev[2] --> curr[]]
prev[x] --> curr[,]
prev[y] --> curr[}]
parse_define_vector_statement() - INFO - Added new local vector: w[2]
activate_side_effect() - caller: parse_define_vector_statement()
parse_corpus(00) Subexpr: var w[2] := { x, y };
parse_corpus(00) - Side effect present: true
-------------------------------------------------
prev[z] --> curr[:=]
prev[:=] --> curr[w]
prev[w] --> curr[]
activate_side_effect() - caller: lodge_assignment()
parse_corpus(01) Subexpr: z := w
parse_corpus(01) - Side effect present: true
-------------------------------------------------
5.3
5.3
于 2020-05-28T03:13:32.103 回答