Passing condition as parameter

时光总嘲笑我的痴心妄想 提交于 2020-02-01 04:42:25

问题


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)
{
    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


回答1:


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; });



回答2:


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);
    }
}



回答3:


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.




回答4:


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.




回答5:


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




回答6:


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.




回答7:


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)); 


来源:https://stackoverflow.com/questions/3324023/passing-condition-as-parameter

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!