为什么将函数作为& name和name传递给出不同的指针?

时间:2016-09-25 18:53:50

标签: c++ templates c++11

我有一个函数,我想调用另一个函数并打印其名称并处理其结果。它工作正常

#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传递,则它不再正常工作(地图中的指针找不到名称)。为什么会这样?我认为应该完全一样。

1 个答案:

答案 0 :(得分:3)

你被函数参数声明的隐式转换命中了。由于您无法将函数作为参数传递给函数,因此编译器(默默地 - 恕我直言应至少应该是警告)将函数类型转换为指针类型。所以当你宣布:

void api_exec(int func(Args...), Args... args)

它真的好像你宣布了

void api_exec(int (*func)(Args...), Args... args)

这意味着当您在&func中使用api_exec时,您将获得指向参数的指针(所以指向指针的指针),而不是参数的值。

阵列也会发生同样的事情,这也会使那些没有意识到的人感到困惑。