1

So I can pass by reference, and store that reference in a structure or class, and if I make changes elsewhere and check that reference again where I stored it the changes will be there because I'm just accessing the same memory.

Is there a library that will let me do something like this:

int foo = 9;
int bar = 5;
// obviously other arithmetic would exist too, and could be combined
Equation foo_minus_bar = Subtract(foo, bar);

// output: 4
cout << foo_minus_bar << endl;

foo = 11;

// output: 6
cout << foo_minus_bar << endl;

It would also be nice if I could access the inputs (preferably as a flat array or similar, but beggars can't be choosers, and maybe even something like this:

// literal character for character output: foo - bar
cout << foo_minus_bar.formula() << endl;

I could make one myself, but I'd rather not reinvent the wheel if it exists.

Shefeto
  • 138
  • 9
  • 1
    Something like ... Oh. You are literally trying to "bind" values to your function and create a reference for it. I'll let a better C++ expert answer this one then. As a start: http://www.cplusplus.com/reference/functional/bind/ – Michael Dorgan Apr 09 '19 at 03:37
  • Seems like a solution, though the result will probably look more "hacky" than I wish! I'll even try it out with lambdas :) – Shefeto Apr 09 '19 at 03:55

1 Answers1

2

The question of OP reminds me to another answer where I modeled an AST for a small example compiler with functor-like classes: The Tiny Calculator Project.

In that project the AST expression nodes have ownership of their child (expression) nodes.

I'm not sure whether I read the intention of OP correctly but, of course, it can be designed as well with expression nodes which don't have ownership of child (expression) nodes.

Thus, I made another (even shorter) example. Additionally, I overloaded operator()() (instead of a virtual solve() member function). Though, in this case, I consider it as a matter of taste.

Sample code:

#include <iostream>

struct Expr {
  virtual int operator()() const = 0;
};

struct ExprConst: Expr {
  const int value;
  ExprConst(int value): value(value) { }
  virtual int operator()() const { return value; }
};

struct ExprRef: Expr {
  const int &ref;
  ExprRef(const int &ref): ref(ref) { }
  virtual int operator()() const { return ref; }
};

struct ExprBin: Expr {
  const Expr &arg1, &arg2;
  ExprBin(const Expr &arg1, const Expr &arg2):
    arg1(arg1), arg2(arg2)
  { }
};

struct ExprSub: ExprBin {
  ExprSub(const Expr &arg1, const Expr &arg2):
    ExprBin(arg1, arg2)
  { }
  virtual int operator()() const { return arg1() - arg2(); }
};

int main()
{
  int foo = 9;
  int bar = 5;
  ExprRef exprFoo(foo), exprBar(bar);
  ExprSub exprSub(exprFoo, exprBar);
  std::cout << "foo - bar: " << exprSub() << '\n';
  std::cout << "foo = 7; bar = 10;\n";
  foo = 7; bar = 10;
  std::cout << "foo - bar: " << exprSub() << '\n';
  // done
  return 0;
}

Output:

foo - bar: 4
foo = 7; bar = 10;
foo - bar: -3

Live Demo on coliru

Scheff's Cat
  • 16,517
  • 5
  • 25
  • 45
  • Yeah, that is similar to what I planned to do if there was no existing library, thanks. – Shefeto Apr 09 '19 at 06:26
  • 1
    @Shefeto There are surely libraries which cover this - most compilers I know use some kind of AST. One of the most popular is probably [LLVM](https://en.wikipedia.org/wiki/LLVM) with [LLVM AST](https://llvm.org/docs/tutorial/LangImpl02.html). On the other hand, such libraries might be highly sophisticated and not quite easy to master. So, an alternative might be to just model on your own exactly what is sufficient to your individual requirements. (Btw. questions for libraries are actually off-topic in SO.) ;-) – Scheff's Cat Apr 09 '19 at 06:34