【问题标题】:Passing parameters to function pointer将参数传递给函数指针
【发布时间】:2016-11-07 20:28:34
【问题描述】:

我正在尝试将参数传递给作为参数传递的函数指针。

代码:

void Test(wchar_t* a, wchar_t* b)
{
    // ...
}

void Test2(void(*Func)(wchar_t*, wchar_t*))
{
    // ...
}

int main()
{
    Test2(Test(L"Hello", L"Testing"));
    return 0;
}

我收到此错误:

“void”类型的参数与“void (*)(wchar_t *, wchar_t *)”类型的参数不兼容

如何解决此问题以完成我想要实现的目标?

编辑:抱歉不清楚。我实际上想要完成的是将一个函数注入一个子进程并传递两个参数(wchar_t*、wchar_t*),以便我可以使用它们。但主函数可以是 void 或 int argc, char** argv。所以我通过简单地使用全局变量来完成我想要实现的目标

【问题讨论】:

  • 一个 lambda 可能就足够了,这取决于你想要做什么。
  • 您想要实现的究竟是什么?正如您所注意到的,您的代码不是有效的 C,因此它不是您意图的有用演示。
  • πάντα ῥεῖ 的答案是我想要实现的,但我想要一种不同的方式来做到这一点,就像在 C++ 中使用模板一样

标签: c++


【解决方案1】:

你可能想要类似的东西

void Test2(void(*Func)(wchar_t*, wchar_t*),wchar_t* x, wchar_t* y)
{
    (*Func)(x,y);
}

int main()
{
    Test2(Test,L"Hello", L"Testing");
    return 0;
}

改为。


至于你的评论

如何在 C++ 中使用模板做到这一点?

我能想到

template<typename Param>
void Test2(void(*Func)(Param, Param), Param x, Param y) {
    (*Func)(x,y);
}

void Test(wchar_t* a, wchar_t* b);

int main() {
    Test2(Test,L"Hello", L"Testing");
    return 0;
}

这应该可以正常工作。

【讨论】:

  • 你的答案就是我想要达到的目标。我如何在 C++ 中使用模板做到这一点?
  • @user1304765 更新了我的答案。仍然不确定你真正想要什么。
  • 是的,它实际上有点复杂。我有一个将代码(函数)注入子进程的函数,因此它具有以下参数:int(Main)(wchar_t, wchar_t*)。我传递给它的 Main 函数调用了一个需要两个 wchar_t* 的函数。
  • @user1304765 好吧,我认为模板函数的需求并不大。我希望您的 child process 实际上是一个线程。您不能更改 main() 的签名并传递任意参数类型。
  • @user1304765 在程序中调用main 不是一个好主意。事实上,它被标准禁止(参见第 3.6.1 节)。如果这是一个错误的沟通,很好,但如果不是,我建议重新考虑。
【解决方案2】:

解决此问题的方法不止一种,但是,让我尝试说明为什么会发生此错误。

每个函数都有一种与之关联的值。这意味着,每个函数都会计算出某种类型的值。这由它的返回值表示。

例如:

int foo(/*whatever*/); 

计算为 int。所以foo(/*whatever*/) 可以在任何需要int 的地方使用。比如int a = b + foo(/*whatever*/)

同样float bar(/*whatever*/); 的计算结果为float,因此bar(/*whatever*/) 可以在任何需要浮点数的地方使用。比如float a = b + bar(/*whatever*/)

返回 void 的函数类似于 void foobar(/*whatever*/),但其计算结果为 void,并且 不能 用于需要某种类型(例如 int、float 等)的值。

现在开始编写代码。 main 函数中的这一行有问题:

int main()
{
    Test2(Test(L"Hello", L"Testing")); /* Issue here */
    return 0;
} 

在这里,您将 Test(L"Hello", L"Testing") 作为参数传递给 Test2。现在请记住,Test(/*whatever*/) 的计算结果为 void,因为 Test 返回一个 void。

所以你在该行中所做的类似于

Test2(/*something that evaluates to a void*/);

但是,Test2 需要 void (*)(wchar_t*, wchar_t*),这是一个 pointer to a function that returns void,与 void 不同。

所以发生的情况是,编译器看到您在预期 void (*) (wchar_t*, wchar_t*) 的地方传递了 void,因此它正确地指示了该错误。

可以有不同的方法来解决其他答案中提到的这个问题。

【讨论】:

    【解决方案3】:

    我需要使用 C++ 模板吗?

    当然,您可以使用 C++ 模板,如下所示:

    #include<utility>
    
    // ...
    
    template<typename F, typename... A>
    void Test2(F &&f, A&&... a)
    {
        std::forward<F>(f)(std::forward<A>(a)...);
        // ...
    }
    
    // ...
    
    Test2(Test, L"Hello", L"Testing");
    

    但你不需要他们做你想做的事。
    @πάνταῥεῖ 已经在其回答中解释了原因。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-11-26
      • 1970-01-01
      • 2018-08-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多