5

我想要一个类,它能够将一个指向函数的指针和一个指向结构的指针作为其字段保存为参数。该对象的接口将是一个不带参数但将保存的参数传递给上述函数的方法 call()。用于不同参数类型和计数的此类类的家族将具有共同的抽象祖先,调用是虚拟的。

至于现在我有以下代码可以工作,尽管将 -pedantic 选项添加到 g++ 会产生错误:

class Function {
    protected:
    void *data;
    void *function;
    public:
    virtual void call() = 0;
};

class SingleArgumentFunction : public Function {
    public:
    SingleArgumentFunction( void (*f)(int), int i ) {
        int *icpy = new int(i);
        function = (void*) f;
        data = (void*) icpy;
    }
    ~SingleArgumentFunction() { delete (int*)data; }
    inline void call() {
        ( *((void (*)(int))function) )( *(int*)data );
    }
};

我得到的错误正如标题所说:

warning: ISO C++ forbids casting between pointer-to-function and pointer-to-object

如何处理?

4

2 回答 2

10

不要将pointer-to-function转换为pointer-to-object,它们不能保证具有相同的大小。void(*)()您将能够通过使用函数指针来解决此问题。

C99 [6.2.5/27]:

指向 void 的指针应具有与指向字符类型的指针相同的表示和对齐要求。类似地,指向兼容类型的合格或不合格版本的指针应具有相同的表示和对齐要求。所有指向结构类型的指针都应具有彼此相同的表示和对齐要求。所有指向联合类型的指针都应具有彼此相同的表示和对齐要求。指向其他类型的指针不需要具有相同的表示或对齐要求。

C99 [6.3.2.3/8]:

指向一种类型的函数的指针可以转换为指向另一种类型的函数的指针,然后再返回;结果应与原始指针比较。

取自其他 SO answer的参考资料。


顺便说一句,您似乎正在尝试重新创建std::function+std::bind.

std::function< void() > f;
f = std::bind( &some_function_that_takes_an_int, 42 );

f(); // look ma! no arguments
于 2013-01-27T02:21:12.490 回答
4

如果您被迫使用需要函数指针的 API void*,您可以在生成警告的语句前加上前缀以__extension__使该警告静音。由于它是 gcc 特定的,因此最好保护这个词,即:

#ifdef __GNUC__
__extension__
#endif
the_statement_that_includes_the_cast;

来自http://trac.osgeo.org/qgis/ticket/234

于 2013-09-30T11:26:50.300 回答