【问题标题】:C++ address of overloaded function重载函数的C++地址
【发布时间】:2017-12-22 03:01:10
【问题描述】:

在我的项目中,我想做如下的事情:

static void test0(void)
{
    printf("%s [%d]\n", __func__, __LINE__);
}

static void test0(int a)
{
    printf("%s [%d] %d\n", __func__, __LINE__, a);
}

static std::map<std::string, void*> initializeAddressMap()
{
    std::map<std::string, void*> addressmap;
    addressmap["test0"] = (void*) &test0;    // ERROR HERE <------
    return addressmap;
}

基本上,第三个函数返回string 到函数地址的映射。然而,此时,我得到一个错误address of overloaded function with no contextual type information,这也是有道理的,因为我已经重载了test0 函数,而此时编译器不知道该取哪个函数的地址。除了调用我的函数不同的名称之外,我有什么办法可以解决这个问题?

【问题讨论】:

标签: c++


【解决方案1】:

最简单的解决方案是将指向重载函数的指针存储在一个指针中,首先:

#include <cstdio>

static void test0(void)
{
    printf("%s [%d]\n", __func__, __LINE__);
}

static void test0(int a)
{
    printf("%s [%d] %d\n", __func__, __LINE__, a);
}

int main(void) {
    void (*select1)(void) = test0;  // will match void(void)
    void (*select2)(int) = test0;   // will match void(int)

    select1();
    select2(42);

    return 0;
}

$ ./a.out
测试0 [5]
测试0 [10] 42

如果要调用存储的void*,则必须再次将其设为函数指针。你可以这样做,例如reinterpret_cast&lt;void(*)(int)&gt;(p).

【讨论】:

  • 我真的需要将地址放入std::map&lt;std::string, void*&gt; addressmap ......这怎么可能?对不起,如果我问菜鸟问题...
  • 您可以通过reinterpret_cast 将函数指针指向void*,但这很可能不是您想要做的。
  • addressmap["test0"]=reinterpret_cast&lt;void *&gt;(select1); 有点工作,但是当我从地图中提取 void* 元素时,看起来我无法用它调用函数......
  • 请看我添加的段落。
【解决方案2】:

获取函数地址时需要定义指针类型:

#include <iostream>

static void test(void)
{
    printf("%s [%d]\n", __func__, __LINE__);
}

static void test(int a)
{
    printf("%s [%d] %d\n", __func__, __LINE__, a);
}

int main()
{
    using t_pf1 = void (*)(void);
    using t_pf2 = void (*)(int);
    ::std::cout << (uintptr_t) t_pf1{&test} << "\n"
      << (uintptr_t) t_pf2{&test} << ::std::endl;
    return 0;
}

working code online

【讨论】:

  • @AksimElnik 好吧,你可以将它们施放为 void * 并像你已经做的那样挤进地图。
  • (*) 有什么作用?如果我有更多函数的地址要存储在地图中怎么办?
  • @AksimElnik (*) 是函数指针声明的一部分。如果您有更多具有相同名称的函数,则需要声明更多函数指针类型。您还可以使用Straight Declarations library,它可以以更直观的方式编写函数指针声明,例如ptr&lt; void (int) &gt;
  • @VTT 并将函数指针转换为 void* ,我需要使用 reinterpret_cast 吗?但这似乎不起作用...
  • @AksimElnik 显然不能,因为在将函数指针转换为 void * 后类型信息会丢失。要调用函数,您需要将 void * 转换回正确的函数指针类型。
猜你喜欢
  • 1970-01-01
  • 2011-06-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-03
  • 2015-04-18
  • 2019-03-25
  • 1970-01-01
相关资源
最近更新 更多