【问题标题】:I want to store void pointers to functions along with the type of them我想存储指向函数的 void 指针以及它们的类型
【发布时间】:2011-11-23 05:25:09
【问题描述】:

我正在尝试使向量保存指向函数的 void 指针,这些函数稍后将被安全调用。
所以,可以说我有三个功能。 int a(), void b();, bool c();

我的向量是vector<void *> vec;

还有我的函数,它存储指向函数的指针。

void registerFunction(void *func)
{
    vec.push_back(func);
}

现在我的问题是当试图调用所有存储的函数时,因为它们都是空指针,我不能在不知道它们的类型的情况下调用这些函数。

所以我的问题是......有什么方法可以存储符号类型,以便我可以将它们与它们各自的指针相关联,然后在调用指向函数的 void 指针时进行类型转换?

注意:函数不一定是类型,例如void (*)(),我也想添加方法,因此即。 void (someclass::)()。是不是要求太多了?它应该工作吗?

【问题讨论】:

  • “指向函数的空指针” - 一个矛盾的终点。 (您最多可以获得与其对应的内存地址,但是您将离开 C++ 规范)

标签: c++ function casting void-pointers


【解决方案1】:

您不能将函数指针转换为void*。这是不允许的。

如果所有函数都可以用零参数调用并且您不关心返回类型,则可以使用std::vector<std::function<void()>>(如果您的 C++ 标准库不支持,function 也可以在 Boost 和 TR1 中找到它)。

不过,如果我没记错的话,C++11 std::function 实现中不允许返回类型转换,在这种情况下,您可能需要以下内容:

template <typename T>
struct ignore_result_impl
{
    ignore_result_impl(T fp) : fp_(fp) { }
    void operator()() { fp_(); }
    T fp_;
};

template <typename T>
ignore_result_impl<T> ignore_result(T fp)
{
    return ignore_result_impl<T>(fp);
}

int g() { return 42; }
std::function<void()> f(ignore_result(g));

(在 Boost 实现中,我知道您可以直接使用 function&lt;void()&gt;,但我很确定在 C++11 中不再允许这样做。我可能是错的,如果在 cmets 中进行澄清,我将不胜感激有人知道。)

【讨论】:

  • 我认为它实际上是允许的(即,它不是违反约束的),但是转换的行为(不仅仅是结果)是未定义的。至少在 C 语言中是这样的; C++ 可能会有所不同。
  • @KeithThompson 未定义与不被允许几乎相同。
  • @R.MartinhoFernandes:我不会这么说。需要实现诊断的错误(语法错误和违反约束)与不需要诊断的错误之间存在很大差异;了解这种区别是最不重要的。有时代码需要是不可移植的;这样的代码通常会执行标准未定义的行为,尽管它可能由其他东西定义。例如,POSIX dlsym 函数依赖于将 void* 转换为函数指针的能力。
【解决方案2】:

void* 不能安全地用作通用的指向函数的指针类型(尽管您可能能够摆脱它)。

但是任何函数到指针的值都可以转换为另一种函数指针类型并再次返回而不会丢失信息。因此,您可以使用,例如,void (*)()(指向返回 void 且不带参数的函数的指针)作为泛型函数指针类型。

至于存储类型,我不确定这是否可能。如果可能性有限,可以使用枚举类型和 switch 语句。

但是使用基于继承的设计可能会更好。

【讨论】:

    【解决方案3】:

    只要所有函数都遵循相同的类型签名,您就可以将 void 指针转换回该类型。

    更好的解决方案是对函数类型进行typedef:

    typedef int(*fun_ptr)();
    vector<fun_ptr> vec;
    

    那么你就不需要演员表了。

    【讨论】:

    • +1 表示 fun_ptr 的想法。 -1 表示您可以将指针返回(是的,您可以将它们强制转换;不,您不能声称您正在将某些东西“返回”;您正在将其强制转换为“某物” - 未定义)
    猜你喜欢
    • 2018-04-06
    • 1970-01-01
    • 1970-01-01
    • 2013-07-19
    • 2016-11-23
    • 1970-01-01
    • 2018-04-19
    • 1970-01-01
    • 2018-08-10
    相关资源
    最近更新 更多