C++将函数作为void指针参数传递给另一个函数

4
我正在尝试将一个函数作为参数传递给另一个带有void指针的函数,但它不起作用。
#include <iostream>
using namespace std;

void print()
{
    cout << "hello!" << endl;
}

void execute(void* f()) //receives the address of print
{
    void (*john)(); // declares pointer to function
    john = (void*) f; // assigns address of print to pointer, specifying print returns nothing
    john(); // execute pointer
}

int main()
{
    execute(&print); // function that sends the address of print
    return 0;
}

这里讨论的是空指针函数,我可以编写更简单的代码,如下所示:
#include <iostream>
using namespace std;

void print();
void execute(void());

int main()
{
    execute(print); // sends address of print
    return 0;
}

void print()
{
    cout << "Hello!" << endl;
}

void execute(void f()) // receive address of print
{
    f();
}

我想了解一下能否使用空指针。

这是为了实现类似这样的功能。

void print()
{
    cout << "hello!" << endl;
}

void increase(int& a)
{
    a++;
}

void execute(void *f) //receives the address of print
{
    void (*john)(); // declares pointer to function
    john = f; // assigns address of print to pointer
    john(); // execute pointer
}

int main()
{
    int a = 15;
    execute(increase(a));
    execute(&print); // function that sends the address of print
    cout << a << endl;
    return 0;
}

1
为什么它不起作用? - mfontanini
void execute(void* f()) 在语法上不正确。 - Mats Petersson
1
我知道,我在请求更正。 - Ricardo Zorio
2个回答

5

使用 gcc test.cpp 命令,我得到以下结果:

test.cpp: In function ‘void execute(void* (*)())’:
test.cpp:12:22: error: invalid conversion from ‘void*’ to ‘void (*)()’ [-fpermissive]
test.cpp: In function ‘int main()’:
test.cpp:18:19: error: invalid conversion from ‘void (*)()’ to ‘void* (*)()’ [-fpermissive]
test.cpp:9:6: error:   initializing argument 1 of ‘void execute(void* (*)())’ [-fpermissive]
< p >参数 f 的签名不正确。您需要使用正确的签名。

void execute(void (* f)())

因此,在将值分配给john时,您不需要进行转换:

john = f

此外,您可以通过直接调用f来简化此过程:
f(); // execute function pointer

编辑: 由于你想使用空指针,所以你需要将 f 作为空指针传递:

void execute(void *f)

在这里,你需要将分配任务给john,但是由于f已经是一个void *,所以不需要转换类型。 注意: 由于你正在传递一个空指针,execute函数将接受任何参数。如果你传入了错误的参数,你将会在运行时出现错误。例如:
void print_name(const char *name)
{
    printf("%s", name);
}

void execute1(void *f);
void execute2(void (*f)());

int main()
{
    int value = 2;
    execute1(&value); // runtime crash
    execute1(&print_name); // runtime crash
    execute2(&value); // compile-time error
    execute2(&print_name); // compile-time error
}

使用特定定义的函数指针可以让编译器在传递错误的参数类型时生成错误。这比运行时崩溃更可取,因为运行时崩溃可能会被利用成安全漏洞,并需要进行大量测试以确保不会发生此类错误。


那么这就不可能了吗?我的意思是,使用函数传递一个空指针?谢谢。 - Ricardo Zorio
传递“带有函数的空指针”是什么意思?你是指传递一个返回另一个函数指针的函数吗(这是可以做到的)? - reece
抱歉,我的意思是“使用void指针将函数作为参数传递给另一个函数,以便稍后指定函数结构”。 - Ricardo Zorio
你不能将函数地址分配给void指针。这在特定平台上可能有效,但在C和C++中是非法的。如果你想要一个函数指针,请使用函数指针。如果你不想指定函数签名,请使用模板。 - bstamour

0

使用

void execute(void (*f)()) //接收print的地址

或者更好的方法是:

void execute(boost::function<void()> const & f) //接收print的地址

也可以接受functors,如果你使用支持C++11的编译器,可以将boost::替换为std::


为什么要使用std::function而不是普通指针?也许某些(旧的)API需要C风格函数,替换所有出现的内容并不安全,如果没有一个好的委托实现,我认为你不应该这样做。 - WorldSEnder

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接