Sign in to follow this  

Passing expressions?

This topic is 4586 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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 this post


Link to post
Share on other sites
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 this post


Link to post
Share on other sites
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 this post


Link to post
Share on other sites
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 this post


Link to post
Share on other sites
<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 this post


Link to post
Share on other sites
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 use
struct 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 this post


Link to post
Share on other sites
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 this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites

This topic is 4586 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this