开发者

Dynamic creation of a pointer function in c++

I was working on my advanced calculus homework today and we're doing some iteration methods along the lines of newton's method to find solutions to things like x^2=2. It got me thinking that I could write a function that would take two function pointers, one to the function itself and one to the derivative and automate the process. This wouldn't be too challenging, then I started thinking could I have the user input a fun开发者_高级运维ction and parse that input (yes I can do that). But can I then dynamically create a pointer to a one-variable function in c++. For instance if x^2+x, can I make a function double function(double x){ return x*x+x;} during run-time. Is this remotely feasible, or is it along the lines of self-modifying code?

Edit:

So I suppose how this could be done if you stored the information in an array and that had a function that evaluated the information stored in this array with a given input. Then you could create a class and initialize the array inside of that class and then use the function from there. Is there a better way?


As others have said, you cannot create new C++ functions at runtime in any portable way. You can however create an expression evaluator that can evaluate things like:

 (1 + 2) * 3

contained in a string, at run time. It's not difficult to expand such an evaluator to have variables and functions.


You can't dynamically create a function in the sense that you can generate raw machine code for it, but you can quite easily create mathematical expressions using polymorphism:

struct Expr
{
  virtual double eval(double x) = 0;
};

struct Sum : Expr
{
  Sum(Expr* a, Expr* b):a(a), b(b) {}
  virtual double eval(double x) {return a->eval(x) + b->eval(x);}
private:
  Expr *a, *b;
};

struct Product : Expr
{
  Product(Expr* a, Expr* b):a(a), b(b) {}
  virtual double eval(double x) {return a->eval(x) * b->eval(x);}
private:
  Expr *a, *b;
};

struct VarX : Expr
{
  virtual double eval(double x) {return x;}
};

struct Constant : Expr
{
  Constant(double c):c(c) {}
  virtual double eval(double x) {return c;}
private:
  double c;
};

You can then parse your expression into an Expr object at runtime. For example, x^2+x would be Expr* e = new Sum(new Product(new VarX(), new VarX()), new VarX()). You can then evaluate that for a given value of x by using e->eval(x).

Note: in the above code, I have ignored const-correctness for clarity -- you should not :)


It is along the lines of self-modifying code, and it is possible—just not in "pure" C++. You would need to know some assembly and a few implementation details. Without going down this road, you could abstractly represent operations (e.g. with functors) and build an expression tree to be evaluated.

However, for the simple situation of just one variable that you've given, you'd only need to store coefficients, and you can evaluate those for a given value easily.

// store coefficients as vector in "reverse" order, e.g. 1x^2 - 2x + 3
// is stored as [3, -2, 1]
typedef double Num;
typedef vector<double> Coeffs;
Num eval(Coeffs c, Num x) {
  assert(c.size()); // must not be empty
  Num result = 0;
  Num factor = 1;
  for (Coeffs::const_iterator i = c.begin(); i != c.end(); ++i) {
    result += *i * factor;
    factor *= x;
  }
  return result;
}

int main() {
  Coeffs c;       // x^2 + x + 0
  c.push_back(0);
  c.push_back(1);
  c.push_back(1); 
  cout << eval(c, 0) << '\n';
  cout << eval(c, 1) << '\n';
  cout << eval(c, 2) << '\n';
}


You don't really need self modifiying code for that. But you will be writing what comes down to an expression parser and interpreter. You write the code to parse your function into suitable data structures (e.g. trees). For a given input you now traverse the tree and calculate the result of the function. Calculation can be done through a visitor.


You don't need to know assembly. Write c++ code for the possible expressions, and then write a compiler which examines the expression and choose the appropriate code snippets. That could be done at runtime like an interpreter usually does, or it could be a compile phase which creates code to execute by copying the instructions from each expression evaluation into allocated memory and then sets it up as a function. The latter is harder to understand and code, but will perform better. But for the development time plus execution time to be less than an interpreted implementation, the compiled code would have to be used lots (billions) of times.


As others have mentioned. Writing self-modifying code isn't necessary at all and is painfull in a compiled language if you want it to be portable. The hardest part of your work is parsing the input. I recommend muParser to evaluate your expressions. It should take away a lot of pain and you would be able to focus on the important part of your project.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜