Problem: The following code would be very expressive and concise, if not necessarily fast, were it not for the fact that it does not compile.
It does not compile because you cannot compare std::function instances with operator==(). And std::find() tries to do exactly that.
Of course, I could go for an entirely different kind of implementation, but stubborn as I am and fond as I am with the code below, I am looking for something "closest as possible" which works.
Who can provide me a pretty rewrite of the code below which does the same thing?
#include <functional>
#include <vector>
typedef std::function<bool(int)> Tester_t;
typedef std::vector<Tester_t> TesterSet_t;
bool Test(TesterSet_t &candidates, int foo)
{
TesterSet_t dropouts;
for( auto& tester : candidates )
{
if(!tester(foo))
{
droputs.push_back(tester);
}
}
while(!dropouts.empty())
{
// The following line is not compiling because std::function has no operator==()
TesterSet_t::iterator culprit =
std::find( candidates.begin(), candidates.end(), dropouts.back() );
candidates.erase(culprit);
dropouts.pop_back();
}
return !candidates.empty();
}
As others have said, you don't need comparison of std::function
s for this. Using standard C++ facilities this can be efficiently (with linear complexity) implemented in two lines:
bool Test(TesterSet_t &candidates, int foo)
{
candidates.erase(std::remove_if(candidates.begin(), candidates.end(),
[foo](Tester_t& f){ return !f(foo); }), candidates.end());
return !candidates.empty();
}
You don't need equality here. Just erase as you go
for (auto it = candidates.begin(); it != candidates.end(); ) {
if (! (*it)(foo) ) {
it = candidates.erase(it);
}
else {
++it;
}
}
return !candidates.empty();
This will be also be faster than the version in the question even if operator==
was defined for std::function
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With