如何将各种类型的函数指针存储在一起?

时间:2011-07-10 09:21:43

标签: c++ c function-pointers

可以使用通用void*存储正常指针。 e.g。

void* arr[10];
arr[0] = pChar;
arr[1] = pINt;
arr[2] = pA;

有时回来,我遇到一个讨论,void*可能无法在所有平台(例如64位及更多)中存储没有数据丢失的函数指针。我不确定这个事实。

如果这是真的,那么存储函数指针集合的最便携方式是什么? [注意:This question没有令人满意地回答这个问题。]

编辑:我将使用索引存储此函数指针。每当访问此集合时,都会对每个索引进行类型转换。截至目前,我只对制作一个数组或vector感兴趣。]

4 个答案:

答案 0 :(得分:9)

您可以将函数指针转换为任何函数类型的另一个函数指针,然后返回而不会丢失。

因此,只要通过函数指针进行调用,首先将其类型转换回正确的类型,就可以将所有函数指针存储在以下内容中:

typedef void (*fcn_ptr)(void);  // 'generic' function pointer

fcn_ptr arr[10];

答案 1 :(得分:6)

指向函数的指针可以转换为指向具有reinterpret_cast的不同类型函数的指针。如果将其转换回原始类型,则可以保证返回原始值,以便您可以使用它来调用该函数。 (ISO / IEC 14882:2003 5.2.10 [expr.reinterpret.cast] / 6)

您现在只需要为数组选择任意函数指针类型。 void(*)()是一种常见的选择。

E.g。

int main()
{
    int a( int, double );
    void b( const char * );

    void (*array[])() = { reinterpret_cast<void(*)()>(a)
                        , reinterpret_cast<void(*)()>(b) };

    int test = reinterpret_cast< int(*)( int, double) >( array[0] )( 5, 0.5 );
    reinterpret_cast< void(*)( const char* ) >( array[1] )( "Hello, world!" );
}

当然,如果通过指向不同类型函数的指针调用函数,则会丢失很多类型安全性并且未定义行为

答案 2 :(得分:3)

使用函数指针类型的并集,这适用于C和C ++,并确保指针有足够的存储空间(可能大小相同,仍然......)。

答案 3 :(得分:2)

有一些东西构成了函数指针的类型。

  • 代码的内存地址
  • 参数签名
  • 联动/名称修改
  • 召集惯例
  • 用于会员功能,some other stuff too

如果这些功能在您的功能指针中不一致,那么您就无法明智地将它们存储在同一个容器中。

您可以bind different aspects进入std::function这是一个可调用的对象,只需要参数签名和返回类型是统一的。

现在可能是在虚拟功能方面重新思考问题的好时机。这个函数指针的混搭是否具有可以表达的连贯接口?如果没有,那么无论如何你都注定要失败: - )

RE:Hasturkun,你可以在工会中存储异构函数指针,是的,它们只是POD,但你还需要存储有关它的指针类型的信息,以便你可以选择要调用的正确成员。这有两个问题:

  • 有一个项目开销,
  • 你必须手动检查你是否一直使用正确的一个,这是非本地效应的负担 - 这是一种传播毒药。

每个类型最好有一个容器,它将澄清代码并使其更安全。或者,使用std::function之类的代理使它们具有相同的类型。