我有一个函数,我想调用另一个函数并打印其名称并处理其结果。它工作正常
#include <iostream>
#include <string>
#include <map>
std::map<void *, std::string> ptr_map;
#define IS_API_CALL(fun) ptr_map[fun] = __FUNCTION__;
int api_call_bar(double x) {
IS_API_CALL(&api_call_bar);
return 0;
}
std::string getFuncNameByPtr(void * addr) {
for (auto it = ptr_map.begin(); it != ptr_map.end(); ++it) {
if (it->first == addr) return it->second;
}
return "???";
}
template <typename... Args>
void api_exec(int func(Args...), Args... args) {
func(args...);
auto name = getFuncNameByPtr(func); // <-- HERE. &func doesnt work
std::cout << name << " was called\n";
}
int main() {
api_exec(&api_call_bar, 2.0);
}
这个打印api_call_bar was called
,这很好。对我来说有趣的部分是标记为<-- HERE
的部分。如果我将其作为&func
传递,则它不再正常工作(地图中的指针找不到名称)。为什么会这样?我认为应该完全一样。
答案 0 :(得分:3)
你被函数参数声明的隐式转换命中了。由于您无法将函数作为参数传递给函数,因此编译器(默默地 - 恕我直言应至少应该是警告)将函数类型转换为指针类型。所以当你宣布:
void api_exec(int func(Args...), Args... args)
它真的好像你宣布了
void api_exec(int (*func)(Args...), Args... args)
这意味着当您在&func
中使用api_exec
时,您将获得指向参数的指针(所以指向指针的指针),而不是参数的值。
阵列也会发生同样的事情,这也会使那些没有意识到的人感到困惑。