Reputation: 22448
I want to write a method which performs some action until a termination criterion becomes true. This termination criterion should be given by the user, and it can be any criterion.
I was thinking about passing a function with return type boolean (possibly a closure) to the method and call it as the condition of a while loop.
In Python, this would be
class Example:
def doSomething(self, amIDone):
while not amIDone():
something()
return
How can I express this in C++11?
Upvotes: 3
Views: 3506
Reputation: 39916
you could do this using std::function
from the <functional>
headers.
The predicate is looking like this:
bool predicate()
{
...
return false;
}
And this is your class using the predicate functor
struct A
{
void test (std::function<bool(void)> func)
{
while( func() )
{
perform();
}
}
}
and you can call it this way:
A a;
a.test(predicate);
In this example I took the function bool predicate()
as a predicate. But a lambda function or a class defining bool operator()
would have worked the same.
Upvotes: 2
Reputation: 126502
You could make your function a template and let it accept any callable object that returns a bool
. For instance:
template<typename P>
void doSomething(P&& p)
{
while (p())
{
something();
}
}
This is how you could invoke it by passing a lambda, for instance:
int main()
{
// Possibly pass a more clever lambda here...
doSomething([] () { return true; });
}
Of course you could pass a regular functor instead of a lambda:
struct my_functor
{
// Possibly write a more clever call operator here...
bool operator () ()
{
return true;
}
};
int main()
{
doSomething(my_functor());
}
A function pointer is also an option:
// Possibly use a more clever function than this one...
bool my_predicate()
{
return true;
}
int main()
{
doSomething(my_predicate);
}
If you have reasons for not making your function a template (for instance, because it is a virtual
member function of some class), you could use std::function
:
void doSomething(std::function<bool()> p)
{
while (p())
{
something();
}
}
All the examples above will work equally well with std::function
, but this will certainly cost you some run-time overhead (which may be irrelevant for your use cases, though).
Upvotes: 8