C++ exprtk - can it be used within a class?
Asked Answered
T

1

9

I want to call a function of a class from exprtk. (http://www.partow.net/programming/exprtk/)

I want to register a function with this toolkit with symbol_table.add_function. Therefore it is required to derive my class like this from ifunction provided with that toolkit:

 template <typename T>
   struct foo : public exprtk::ifunction<T>
   {
      foo() : exprtk::ifunction<T>(0)
      {}

      T operator()()
      {
         // here I want to access data from a class which owns this struct
      }
   };

Is it possible to include this struct in a way, that a class can access it and the operator() of this struct can access data in the class? One possibility would be to pass a pointer of that class to the constructor of the struct. Is there a better way?

Teddy answered 6/12, 2017 at 11:4 Comment(3)
A pointer would be one option. Another option could be to pass a reference instead. A third option could be to use multiple inheritance i.e. deriving foo from exprtk::ifunction<> and your other class. Without more context it is hard to say which one is the best (or most appropriate). This said, some ad.: If you don't need the complete power of exprtk, you may consider to build your own expression parser. This might be a start: SO: The Tiny Calculator Project.Depurate
So it looks like I have to pass a pointer/reference. Multiple inheritance is not an option, because I need several such functions and each time operator() is called from exprtk.Teddy
"Multiple inheritance is not an option, because I need several such functions and each time operator() is called from exprtk." Multiple inheritance doesn't prevent overloading of operator()() or usage in exprtk. But if instances of multiple classes (inherited from exprtk::ifunction<T>) have to share the data of the same instance of your class then multi inheritance is, of course, not an option. In that case, pointer or reference...Depurate
M
3

The state/data class can either own the ifunction or be passed in as a reference (be sure to manage life-times properly) or via a std::shared_ptr to the ifunction instance:

class my_class
{};

template <typename T>
struct foo : public exprtk::ifunction<T>
{
   foo(my_class& mc)
   : exprtk::ifunction<T>(0)
   , mc_(mc)
   {}

   T operator()()
   {
      return mc_.get_some_value() / 2;
   }

   my_class mc_;
};
Melancholy answered 6/9, 2023 at 7:4 Comment(1)
Finally, I used a different solution. I derived classes/structs from exprtk::expression, exprtk::parser, exprtk::function_compositor and exprtk::symbol_table and used them as member variables of my class. I set the variables (which can be any number now) by using symbol_table::add_variable.Teddy

© 2022 - 2024 — McMap. All rights reserved.