std::function 不起作用,但普通的旧函数指针起作用 - 为什么?
std::function does not work, but plain old function pointer does - why?
我想创建一个将 std::function
作为参数的函数,并在内部调用传递的函数:
void handleCollision(std::function<void(const Entity&)>& resolveCollision, const Entity& block) {
if (playerInRangeOf(block) && playerIntersects(block)) {
resolveCollision(block);
}
}
和来电者(在同一个Class内):
for (auto&& block : blocks) {
handleCollision(resolveCollisionAxisX, block);
}
错误:
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);
^
但是,如果我跟着C风格的函数指针:
void handleCollision(void (StateGame::*resolveCollision)(const Entity&), const Entity& block) {
if (playerInRangeOf(block) && playerIntersects(block)) {
(this->*resolveCollision)(block);
}
}
然后它确实工作正常(调用者是相同的)。
如何使 std::function
正常工作?旁注:我不想让任何东西静态化。
用 lambda 包起来,替换
handleCollision(resolveCollisionAxisX, block)
到
[this](const Entity& e){
this->resolveCollisionAxisX(e);
}
同时将 std::function<void(const Entity&)>&
替换为 std::function<void(const Entity&)>
或 const std::function<void(const Entity&)>&
C++ 成员函数是普通的 C 函数,添加了实例地址作为第一个参数。
例如,编译器的 void StateGame::resolveCollisionAxisX(const Entity&)
等同于
void resolveCollisionAxisX(StateGame* instance, const Entity&)
这里是一个显示工作示例的小代码片段。查看 std::function
模板参数是 void(A*)
而不仅仅是 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();
}
如果知道Python,这个概念就更明确了,其实所有的成员函数都有self
作为第一个参数(也就是this
的分身) C++).
我想创建一个将 std::function
作为参数的函数,并在内部调用传递的函数:
void handleCollision(std::function<void(const Entity&)>& resolveCollision, const Entity& block) {
if (playerInRangeOf(block) && playerIntersects(block)) {
resolveCollision(block);
}
}
和来电者(在同一个Class内):
for (auto&& block : blocks) {
handleCollision(resolveCollisionAxisX, block);
}
错误:
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);
^
但是,如果我跟着C风格的函数指针:
void handleCollision(void (StateGame::*resolveCollision)(const Entity&), const Entity& block) {
if (playerInRangeOf(block) && playerIntersects(block)) {
(this->*resolveCollision)(block);
}
}
然后它确实工作正常(调用者是相同的)。
如何使 std::function
正常工作?旁注:我不想让任何东西静态化。
用 lambda 包起来,替换
handleCollision(resolveCollisionAxisX, block)
到
[this](const Entity& e){
this->resolveCollisionAxisX(e);
}
同时将 std::function<void(const Entity&)>&
替换为 std::function<void(const Entity&)>
或 const std::function<void(const Entity&)>&
C++ 成员函数是普通的 C 函数,添加了实例地址作为第一个参数。
例如,编译器的 void StateGame::resolveCollisionAxisX(const Entity&)
等同于
void resolveCollisionAxisX(StateGame* instance, const Entity&)
这里是一个显示工作示例的小代码片段。查看 std::function
模板参数是 void(A*)
而不仅仅是 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();
}
如果知道Python,这个概念就更明确了,其实所有的成员函数都有self
作为第一个参数(也就是this
的分身) C++).