Reputation: 139
I want to pass a function from another class as parameter in my current class. I'm trying to do something like this (I siplified the code, so you still can get the idea):
B class:
bool B::myCmpFunc(int a, int b) {
return a > b;
}
vector<int> B::sort(bool (*cmp)(int a, int b)) {
vector<int> elems = getElems();
for (int i = 0; i < elems.size() - 1; i++) {
for (int j = i + 1; j < elems.size(); j++) {
if ((*cmp)(elems[i], elems[j])) {
int aux = elems[i];
elems[i] = elems[j];
elems[j] = aux;
}
}
}
return elems;
}
And I try to call this sort function from A class
:
B b;
auto sortedElems = b.sort(&b.myCmpFunc);
The problem is I get this error when I try to pass &b.myCmpFunc as parameter in A class
:
Error C2276 '&': illegal operation on bound member function expression
I also tried another things, like passing the function as b.myCmpFunct
, B::myCmpFunc
, &B::myCmpFunc
, but I still got errors.
Upvotes: 1
Views: 2453
Reputation: 140880
When you have a class
function (non static function inside a class), you need to pass this
/the instance of the class around, so the compiler can pass this
/the instance of the object to the function, when it invokes it.
You can:
static
. static
functions inside a class don't use this
/ the object instance, so their pointers are normal.static bool B::myCmpFunc(int a, int b) {}
b.sort(&b.myCmpFunc);
// or
b.sort(&B::myCmpFunc);
std::function
and bind this
with object pointer using std::bind
.vector<int> B::sort(std::function<bool(int a, int b)> cmp) {
... no changes ...
}
b.sort(std::bind(&B::myCmpFunc, &b, std::placeholders::_1, std::placeholders::_2));
B
class functions.vector<int> B::sort(bool (B::*cmp)(int a, int b)) {
...
(this->*cmp)(...);
...
}
b.sort(&B::myCmpFunc);
b.sort([](int a, int b) -> bool { return a < b; });
// really or
b.sort([&b](int a, int b) -> bool { return b.myCmpFunc(a, b); });
As the member function B::myCmpFunc
doesn't seem to use this
pointer nor object members, I would go with declaring it static
.
Upvotes: 1
Reputation: 38267
You mix up pointers to ordinary functions and pointer to member functions. Those are different concepts, that are worth understanding at some point. What you can do is to make the comparison function a static
and then pass a pointer to it like this:
auto sortedElems = b.sort(&B::myCmpFunc);
Otherwise, you can implement myCmpFunc
as a free function, i.e., not bound to a class. Then pass it as
auto sortedElems = b.sort(&myFreeCmpFunc);
In any case, it doesn't make much sense to have a member function myCmpFunc
that has no dependency on the state of its object. Making it a free function increases encapsulation and makes the comparison function reusable (apart from the fact that you could also use a std::greater<>{}
function object instead.
Upvotes: 1