clstaudt
clstaudt

Reputation: 22448

Boolean function as input parameter

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

Answers (2)

Stephane Rolland
Stephane Rolland

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

Andy Prowl
Andy Prowl

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

Related Questions