开发者

Passing condition as parameter

First of all to explain what I'm trying to do:

void Foo(int &num, bool condition);

Foo(x, x > 3);

This code basically would evaluate the bool of the condition before calling the function and then pass pure true or false. I'm looking for a way to make it pass the condition itself, so I could do something like this:

void Foo(int &num, bool condition)开发者_JAVA技巧
{
    while(!condition)
    {
        num = std::rand();
    }
}

I know there could be a workaround by passing a string containing the condition and parsing the latter, and I'm working on it right now, but I find it rather inefficient way. The accepted answer will be the one explaining the solution on any other way beside the one with parsing the string containing the condition, or an answer that clarifies that this way of passing conditions is impossible.

Thanks in advance


One example using a standard library functor:

#include <functional>

template<class UnaryPred> void func(int& num, UnaryPred predicate) {
    while(!predicate(num)) num = std::rand();
}

void test() {
    int i = 0;
    func(i, std::bind1st(std::greater<int>(), 3));
}

See the documentation on <functional> for what C++ already provides you with out-of-the-box.

If your compiler has sufficient support (e.g. GCC 4.5 or VC10), you can also go for lambda functions. E.g. using the same func() as above:

func(i, [](int num) { return num > 3; });


this is called functional programming.

here is snippet using boost::phoenix http://www.boost.org/doc/libs/1_43_0/libs/spirit/phoenix/doc/html/phoenix/starter_kit.html:

using namespace boost::phoenix;

Foo(x, (cref(x) < 3));
// (cref(x) < 3) is expression that creates function object

template<class C> // condition is a monster, make it generic
void Foo(int &num, C condition)
{
    while(!condition()) // notice you call condition as function
    {
        rand(num);
    }
}


What you should do is create a function which tests your condition, then pass a pointer to that function as a parameter. See http://www.cprogramming.com/tutorial/function-pointers.html for details/tutorials on how to do this.


The plausible way to do this would pass a functor - and object that behaves like a function - to the called function, and the called function would invoke the functor to re-evaluate the condition on each iteration of the loop.

Parsing the string is not going to work; the called function does not have access to the local variables of the calling function.


Pass a function to Foo instead. Then you can "delay" the execution of the expression by waiting to call that function.


You can do this without templates or boost (a commenter called this "C-style", which is correct I suppose).

/* have Foo take a pointer to a function that returns bool */
void Foo(int &num, bool (*fcn)(int))
{
    while(!fcn(num))
    {
        num = std::rand();
    }
}

/* You can have all the Comparators you want, 
   as long as they have the same signature */
bool ComparatorOne(int x) { return x > 3 ? true : false; }

bool ComparatorTwo(int x) { return x < 10 ? true : false; }

/* and this is how you call it */
int n;
Foo(n, ComparatorOne);
Foo(n, ComparatorTwo);

Edit

Note that your Comparator can take a different set of parameters, as long as they're consistent.


As others have said, pass a functor object into Foo(). The STL commonly uses this approach. For example:

template< class Func >
void Foo(int &num, Func condition) 
{ 
    while(!condition()) 
    { 
        rand(num); 
    } 
} 

struct GreaterThanThree
{
    int& _num;
    GreaterThanThree(int &num) : _num(num) {}
    bool operator()() const { return (_num > 3); }
};

Foo(x, GreaterThanThree(x)); 
0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜