I want to make a function that will take std::function
as a parameter, and inside call that passed function:
void handleCollision(std::function<void(const Entity&)>& resolveCollision, const Entity& block) {
if (playerInRangeOf(block) && playerIntersects(block)) {
resolveCollision(block);
}
}
And the caller (within the same Class):
for (auto&& block : blocks) {
handleCollision(resolveCollisionAxisX, block);
}
Error:
Reference to non-static member function must be called
error: no matching function for call to 'StateGame::handleCollision(<unresolved overloaded function type>, Block&)'
handleCollision(resolveCollisionAxisX, block);
^
However , if I follow with C-style function pointers:
void handleCollision(void (StateGame::*resolveCollision)(const Entity&), const Entity& block) {
if (playerInRangeOf(block) && playerIntersects(block)) {
(this->*resolveCollision)(block);
}
}
Then it does work fine (caller is the same).
How can I make the std::function
work? Side note: I don't want to make anything static.
Wrap it in a lambda, replace
handleCollision(resolveCollisionAxisX, block)
to
[this](const Entity& e){
this->resolveCollisionAxisX(e);
}
Also replace std::function<void(const Entity&)>&
to std::function<void(const Entity&)>
or const std::function<void(const Entity&)>&
C++ member functions are plain C function with the addition of the instance address as the first parameter.
For instance, void StateGame::resolveCollisionAxisX(const Entity&)
for the compiler is equivalent to void resolveCollisionAxisX(StateGame* instance, const Entity&)
Here a small code snippet showing a working example. See how the std::function
template parameter is void(A*)
and not just void()
.
#include <iostream>
#include <functional>
struct A{
void foo1(void(A::*resolveCollision)(void)){
std::cout << "foo [c-style]" << std::endl;
(this->*resolveCollision)();
}
void foo2(std::function<void(A*)> resolveCollision) {
std::cout << "foo [std::function]" << std::endl;
resolveCollision(this);
}
void target() {
std::cout << "resolve" << std::endl;
}
void caller() {
std::cout << "caller" << std::endl;
foo1(&A::target);
foo2(&A::target);
}
};
int main() {
A a;
a.caller();
}
If you know Python, there it is more explicit this concept, in fact, all member functions have self
as first parameter (which is the alter ego of this
in C++).
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.