user25470
user25470

Reputation: 595

Template with pointer to member function

I'm trying to write a template for a function object to act as a predicate in a STL algorithm function. Im still quite new to this and i cant get it quite right

here is the template:

#ifndef MEMBERPREDICATE_H
#define MEMBERPREDICATE_H

template <typename Type, typename Class>
class MemberPredicate{
public:
    MemberPredicate(Type (Class::*method)(), bool (*operation)(Type,Type), Type data) : method(method), operation(operation), data(data){};
    bool operator()(Class * other){ return *(this->operation)(other->*(this->method)(), this->data);}
private:
    Type (Class::*method)();
    bool (*operation)(Type,Type);
    Type data;
};
#endif

The constructor takes a pointer to a (get)method of the class, a pointer to a comparison operator acting on values returned by that get method and finaly some data that it should use for comparisons

Im trying to use the template in the following way:

bool equal(int a, int b){
    return a == b;
}

MemberPredicate<int, IntClass> pred(&IntClass::getInt, &equal, 4)
IntClass * i = new IntClass(5) // stores 5 in IntClass and returns this value when i->getInt() is called
pred(i);

i can compile just fine when im not using the function part of the function object but when i try to apply it to i i get an error:

Must use '.*' or '->*' to call pointer to member function in Member...
bool operator()(Class * other){ return *(this->operation)(other->*(this->method)(), this->data);}

And here the marker is under the arrow other-> I've tried chaing the arrows to points and to move them around a bit at random but cant get it to work.

As i said im wuite new to this and it might very well be that this is a very strange way to go about things. if thats the case pointers in the right direction are very welcome, but i would still like to grasp this part.

Finally i have a bonus question, I will want to make the get-method const after i get this part working, but im not sure how, any help here would also be nice.

Thank you

Upvotes: 1

Views: 151

Answers (1)

David G
David G

Reputation: 96790

*(this->operation)(other->*(this->method)(), this->data);
^                         ^

Because of operator precedence, the call operator () is invoked before the function pointer is dereferenced. It will only be dereferenced after the call operator is invoked.

Change it to this:

(*this->operation)((other->*(this->method))(), this->data);
 ^                         ^

Notice that I also put another pair of parenthesis around other->*(this->method)(). This is needed because (this->method)() would have been evaluated before other->*.


Also, as @dyp says, you leave out most of the this qualifiers, making the result:

operation((other->*method)(), data);

Upvotes: 2

Related Questions