Many algorithms from the standard library accept a unary predicate with a signature of bool (Type & item)
so supplying a pointer to a non-static member function directly is not working. This seems to be rather restrictive considering that it seems to be possible to lift such a restriction by replacing direct invocation of operator ()
on the predicate with a call to std::invoke
. Maybe the proposed approach has some drawbacks that I've overlooked?
Note: the non-static member function referred to in this question is supposed to differ from a regular function predicate only in that an item reference is passed as an implicit parameter rather than an explicit parameter.
Example code (online compiler):
#include <array>
#include <algorithm>
#include <iostream>
#include <functional>
#include <cassert>
template<typename TForwardIterator, typename TPredicate> TForwardIterator
my_find_if
(
const TForwardIterator p_items_begin
, const TForwardIterator p_items_end
, TPredicate && predicate
)
{
TForwardIterator p_item(p_items_begin);
// while((p_items_end != p_item) && (!predicate(*p_item)))
while((p_items_end != p_item) && (!::std::invoke(predicate, *p_item)))
{
++p_item;
}
return(p_item);
}
class t_Ticket
{
private: int m_number;
public:
t_Ticket(const int number): m_number(number) {}
public: bool
Is_Lucky(void) const {return(8 == m_number);}
};
int main()
{
::std::array<t_Ticket, 10> tickets{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
// using standard library
auto p_ticket1(::std::find_if(tickets.begin(), tickets.end(), [](const t_Ticket & ticket) {return(ticket.Is_Lucky());}));
// still works
auto p_ticket2(my_find_if(tickets.begin(), tickets.end(), [](const t_Ticket & ticket) {return(ticket.Is_Lucky());}));
// same thing, but shorter and not sufferring from potential lambda code duplication
auto p_ticket3(my_find_if(tickets.begin(), tickets.end(), &t_Ticket::Is_Lucky));
// using standard library like this won't compile
//auto p_ticket4(::std::find_if(tickets.begin(), tickets.end(), &t_Ticket::Is_Lucky));
assert(p_ticket1 == p_ticket2);
assert(p_ticket2 == p_ticket3);
return(0);
}