ISO C++禁止在指向函数的指针和指向对象的指针之间进行转换

yau*_*ser 5 c++ function-pointers

我希望有一个类能够保持其字段指向函数的指针和指向结构保持的指针是参数.该对象的接口是一个方法call(),它不带参数,但将保存的参数传递给上面提到的函数.针对不同参数类型和计数的这类类的一族将具有共同的抽象祖先,其中调用是虚拟的.

至于现在我有以下代码可行,虽然向g ++添加-pedantic选项会产生错误:

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 );
    }
};
Run Code Online (Sandbox Code Playgroud)

我得到的错误是标题所示:

warning: ISO C++ forbids casting between pointer-to-function and pointer-to-object
Run Code Online (Sandbox Code Playgroud)

怎么处理?

K-b*_*llo 9

不要将指向函数指针转换指向对象的指针,它们不能保证具有相同的大小.您将能够通过使用void(*)()函数指针来解决此问题.

C99 [6.2.5/27]:

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

C99 [6.3.2.3/8]:

指向一种类型的函数的指针可以被转换为指向另一种类型的函数的指针并且再次返回; 结果应该等于原始指针.

参考文献取自其他SO答案.


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

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

f(); // look ma! no arguments
Run Code Online (Sandbox Code Playgroud)

  • @yauser:您可以将它与`std :: bind`结合使用.`std :: function <void()> f = std :: bind(&your_function,your_arguments ...); F();` (2认同)
  • @yauser:你的意思是功能和对象?不,它们可能并不总是只是一个内存地址.如果我的记忆对我有用,那么指向不同类型的指针也可能有不同的大小.虽然如果那是正确的,那么`void*'必须足够大以容纳其中最大的...我应该回到标准 (2认同)