获取在运行时作为参数传递的重载函数的名称

Posted

技术标签:

【中文标题】获取在运行时作为参数传递的重载函数的名称【英文标题】:Get the name of an overloaded function passed as an argument at run-time 【发布时间】:2019-05-26 13:39:48 【问题描述】:

假设所有包含都已定义,请通过下面定义的代码结构。

std::unordered_map<std::string, void*> callbackReg;

class A

public:
    void foo(int a)
    
        //impl
    
    void foo(int a, int b)
    
        //impl
    
    void foo(int a, double d)
    
        //impl
    

;


template<class Instance , typename Function>
void register_func(Instance& obj, Function func)

    /* have to store function name as the key and 
     - pointer to raw member function pointer as the value, 
     - in callbackReg Map */
    // ---> Point B


int main(int argc, const char * argv[])

    A a;
    register_evt(a, &A::foo); //---> point A
    system("Pause");


问题与讨论

    @Point A 如何解决函数名称范围解析问题,这意味着如何调用重载函数/指向此类函数的指针?没有内联静态转换,因为它有点丑陋和混乱。 @Point B 假设我们已修复重载名称解析问题,现在我们必须存储 成员函数名称其指针值 em>callbackReg 地图中。

我知道这可能会很麻烦,但是,这在 C++ 中可行吗?否则有什么方法可以将 raw memeber funtion pointers 与其他一些键值一起存储,以便将它们用作callbacks。因为在debug 时间,调试器已经知道传递的函数名称是什么作为register_func 模板函数参数。 请看随附的图片。

因此,简单地说,我们如何仅使用原始成员/非成员函数指针实现回调register/unregister 场景? p>

(如果解决方案或方法是一种跨平台方法,将不胜感激,至少基​​于 Win32)

【问题讨论】:

C++ 没有type introspection。您无法从指向函数的指针中获取函数名称。通常的解决方案是将名称作为参数与函数一起传递。调试器可以从编译器与可执行程序文件(在其中或作为单独文件)一起保存的额外信息中获取名称,但此信息通常在发布版本中不可用。 “如何解决函数名称范围解析问题,这意味着如何调用重载函数/指向该函数的指针?”使用static_cast,如果你觉得它很乱,那么请避免使用你的方法来解决问题。 你可以使用宏来表示#define RegisterFunc(obj,func) register_func_and_name(obj,func,#func) “由于在调试时,调试器已经知道传递的函数名是什么......”所以你希望你的程序只有在启用调试的情况下才能工作? @Oliv 这将如何帮助解决重载问题? 【参考方案1】:

你可以使用boost backtrace:

boost::stacktrace::frame 提供有关函数的信息。您可以从函数指针构造该类并在运行时获取函数名称

【讨论】:

非常感谢,我们可以自己实现吗? @Buddhika 是的。您需要有关可执行文件格式和调试信息的知识。 Boost 是开源的,所以只看里面的源代码。希望它有据可查。 @Oliv 对于registerunregister 这样的原始函数指针回调方法有什么更好的模式吗?

以上是关于获取在运行时作为参数传递的重载函数的名称的主要内容,如果未能解决你的问题,请参考以下文章

使用枚举重载 TypeScript 函数

请简述重载和重写的区别

JS--理解参数,argument,重载

函数重载

c++核心编程--函数的重载

什么是 重载 ?为什么要重载?有何特点?