J3STER
J3STER

Reputation: 1075

Function Pointers by Reference

Good Day everybody, I am creating a List class in order to be able to manipulate data like in python, but in c++. I came up with an idea. Basically a method that goes through every node, and deletes it if it meets a specific condition. But I wanted that condition to be determined by the user of the library, so I implemented a pointer to a bool function, that takes one template data (same type as the List) as its only parameter.

So far, I managed to run this...


.h file:

int delIf(bool (*)(T));

.cpp file:

template <typename T>
int List<T>::delIf(bool (*ptr)(T)){
    int tot=0;
    T aux;
    for (int i=0;i<tam;i++)
    {
        aux=(*this)[i]; //Ive overloaded the [], and it works fine
        if ((*ptr)(aux))
        {
            tot++;
            this->del(i);
        }
    }
    return tot;
}

main.cpp:

#include <iostream>
#include "lists.cpp"

using namespace std;

bool check(int);

int main()
{
    List<int> a;
    for (int i=0;i<10;i++)
        a.push(i);
    a.delIf(&check);

    return 0;
}

bool check(int a){
    if (a%2==0)
        return true;
    else
        return false;
}

This works fine, however, I was wondering if its possible to overload the delIf method so that it takes not a pointer to a function as parameter, but a reference to it, so the user of the library could call:

delIf(check); //No '&' required

Instead of the

delIf( & check);

That is currently mandatory. Ive tried changing the prototype to something like:

int delIf(  (bool (*)(T)) & );

but I keep getting errors.

Thanks in Advance Everybody.

Upvotes: 2

Views: 862

Answers (1)

Your premise is false. You don't need an & in front of a function to pass it to delIf. The name of a function decays into a pointer to the function almost everywhere it is used in an expression. (Including when you call the function!) In fact, the only place it doesn't is when it is used as an argument to & - so

func
&func

have exactly the same type and value.

Having said that, yes you can pass a reference. First rule of pointers to functions - write a typedef

typedef bool pred_t(T);
void delIf( pred_t& pred );

But! I strongly encourage you to write delIf as a function template, and allow anything which can be called with a T, and has a function result which can be implicitly converted to bool.

template <typename Pred>
void delIf(Pred pred) {
   ...
}

That will allow use with capturing lambdas, and functors in general.

Also, what is this CPP file of which you speak? Templates have to be implemented in the header file. See the answers to this question.

(Note: "Pred" is short for "predicate" which is what the standard calls this sort of function.)

Upvotes: 6

Related Questions