# Passing expressions?

## Recommended Posts

NIm    210
Is there any way to pass an expression as an argument to a function? I'm asking because I have several occasions where I check alll the squares around a given square, but I'm checking for something different each time. It would neaten up my code considerably if it could be done.

##### Share on other sites
PnP Bios    494
something like this?

int f1(int n);

main()
{
int m1 = 421;
int m2 = f1( (m1+360));
return;
}

or if you wanted to get tricky....

main()
{
int m1 = 46;
int m2 = f1( 144 + f1(32 + f1(75)) + m1);
return;
}

perfectly valid.

##### Share on other sites
Jemburula    341
Yeah, with the example above it evaluates the result THEN passes it to the function.

##### Share on other sites
NIm    210
That's not exactly what I meant. With your example, your still p[assing an integer to the function, not the expression itself. Something like the following:

int eval(expression);{  n=10  return(expression);}int main(){  eval((n+5*4));}

would result in the following being seen by the debugger:

  return (10+5*4);

Obviously, this is a simplistic and pointless example, but it gives the general idea. the function eval would look at a number of structures and return whichever matched the expression.

##### Share on other sites
Drew_Benton    1861
Quote:
 Obviously, this is a simplistic and pointless example, but it gives the general idea. the function eval would look at a number of structures and return whichever matched the expression.

Can you explain some more please? It sounds like you are in need of function templates, but I'm not sure, perhaps another example that is closer to what you want to happen.

In your example above, that will work as long as 'n' was defined and initialized before it was called in that function. Here's a few random links:
Fast regular expressions
MSDN Reference

##### Share on other sites
I think what you want is lambda expression as in Lisp, but C and C++ has no lambda directly built-in.

You may get "similar" effect using function pointer in C and C++, or functor in C++.

##### Share on other sites
PnP Bios    494
<obiewankenobi>C is not the language you are looking for</obiewankenobi>

Yeah, if you wanted to do that in C, you would have to used some messed up templates or function pointers, which would totaly obfuscate your code.

I think you want LISP.

##### Share on other sites
why not simply pass functors?

##### Share on other sites
Zahlman    1682
The abstraction exists in C++, as others have alluded to, and it's not that bad - however, you don't get to create the things in-line so easily:

// This is the "expression" type we will usestruct expression {  virtual int operator() (int n);}// We'll define a subtype of "expression" for each actual formula we need in // the code, then rely on polymorphism.struct squaredPlusFour : expression {  int operator() (int n) { return n*n + 4; }}// Since we're passing in objects and require polymorphism, passing by reference// (or pointer) is critical - otherwise the object will be "sliced"int eval(const expression& e) {  int n=10;  // Apply the formula to the local value  return e(n);}int main() {  // We create an anonymous squaredPlusFour object, and pass it to the function  eval(squaredPlusFour());  // Since it was stack-allocated, it disappears at end of scope}

Java improves on this by allowing you to specify the expression code at the point where you create the object (and also makes all the polymorphism stuff easier to deal with), but worsens it by requiring a normal named method instead of an "operator()" overload. Other languages in the same "family" are generally not much better or worse, and languages that *do* support this sort of thing more easily are... an acquired taste (difficult to get used to unless you start off with them, which is rare these days).

##### Share on other sites
NIm    210
ok, that's kindof helpful, but it smells hard. I'll file this int my todo. exactly what I'm trying to do:
    for(i=0; i<mapmaxy-1; i++)    {      for(j=0; j<mapmaxx-1; j++)      {        k=0;                           //count the neihgbors of a cell        if (map[j+1][i+1].wall==1)          {k++;}                       //if map is to be spherical, have the        if (map[j][i+1].wall==1)       //edges detect neighbors on the other          {k++;}                       //side of the map.        if (map[j-1][i+1].wall==1)          {k++;}        if (map[j+1][i].wall==1)          {k++;}        if (map[j-1][i].wall==1)          {k++;}        if (map[j+1][i-1].wall==1)          {k++;}        if (map[j][i-1].wall==1)          {k++;}        if (map[j-1][i-1].wall==1)          {k++;}      }    }return k;

This particular case counts the number of walls adjoining the square (j,i), but I would like to make it a function that can count monsters, or doors, or open doors with monsters standing in them. thanks for all your help, but it looks ike i've got more to learn before I try something like this.

##### Share on other sites
Telastyn    3777
Your best bet would be to make a function to return a list [std::vector] of all of the neighboring tiles. That list can then be passed to other functions.

It'd be something like this:

vector<tile *>        neighbors(tile *center){//// Return list of tile pointers around center.//vector<tile *>      rtn;// Example, assumes only cardinal movement.rtn.push_back(retrieve_tile(center->x-1, center->y));rtn.push_back(retrieve_tile(center->x, center->y-1));rtn.push_back(retrieve_tile(center->x+1, center->y));rtn.push_back(retrieve_tile(center->x, center->y+1));return(rtn);}struct              wall_accumulator{//////int          operator()(int c,tile *here){       if (here->wall){             return(c+1);       }else{             return(c+0);       }};int                count_walls_around(tile *here){//// Return number of walls around tile "here"//vector<tile *>      n=neighbors(here);return( accumulate(n.begin(), n.end(), 0, wall_accumulator() );}

[edit: I think this is right, but am not that familiar with the Library myself, and don't have a compiler handy to check it.]

You would then just make different accumulators like the wall_accumulator for each of the different things you'd like to count [or do something nifty like pass a pointer_to_member or functor to the accumulator to tell it which thing to count].

The Standard Library is your friend. It's part of the language. It makes repetative, tedious things like this far far easier.