【问题标题】:c++ passing function as argument to another function with void pointerc ++将函数作为参数传递给具有void指针的另一个函数
【发布时间】:2013-06-05 13:56:50
【问题描述】:

我正在尝试将一个函数作为参数传递给另一个带有 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;
}

问题是 void 函数指针,我可以编写更简单的代码,例如

#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 指针

它是为了实现这样的东西

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;
}

【问题讨论】:

  • 怎么不工作?
  • void execute(void* f()) 在语法上不正确。
  • 我知道,我要求更正

标签: c++ function pointers arguments void


【解决方案1】:

使用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]

f 参数的签名不正确。你需要使用

void execute(void (* f)())

相反。因此,分配给john 时不需要演员表:

john = f

另外,您可以通过直接调用f 来简化此操作:

f(); // execute function pointer

编辑:由于要使用 void 指针,因此需要将 f 作为 void 指针传递:

void execute(void *f)

在这里,您需要分配给john,但由于f 已经是void *,您不需要演员表。

注意:假设您传递的是一个 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
}

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

【讨论】:

  • 那么不可能吗?我的意思是,用函数传递一个 void 指针?不过谢谢
  • 传递“带函数的空指针”是什么意思?你的意思是传递一个返回指向另一个函数的指针的函数(你可以这样做)?
  • 抱歉,我提到“使用 void 指针将函数作为参数传递给另一个函数,以便稍后指定函数结构”
  • 您不能将函数的地址分配给 void 指针。它可能适用于特定平台,但它是非法的 C 和 C++。如果需要函数指针,请使用函数指针。如果您不想指定函数签名,请使用模板。
【解决方案2】:

使用

void execute(void (*f)()) //receives the address of print

或者更好的使用:

void execute(boost::function&lt;void()&gt; const &amp; f) //receives the address of print

如果您使用支持 C++11 的编译器,也可以接受函子,或者将 boost:: 替换为 std::

【讨论】:

  • 为什么使用 std::function 而不是普通的指针?也许某些(旧)API 需要 c 风格的函数,替换所有出现的情况并不安全,而且如果没有良好的 Delegate 实现,我认为您不应该
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-08-25
  • 2019-01-28
  • 1970-01-01
  • 1970-01-01
  • 2012-09-10
  • 2021-11-19
  • 1970-01-01
相关资源
最近更新 更多