【问题标题】:std::function -> function pointerstd::function -> 函数指针
【发布时间】:2012-05-11 16:47:01
【问题描述】:

这是一个代码:

#include <functional>
using namespace std::tr1;

typedef void(*fp)(void);

void foo(void)
{

}

void f(fp)
{

}

int main()
{
  function<void(void)> fun = foo;
  f(fun); // error
  f(foo); // ok
}

最初我需要从非静态类方法中创建一个函数指针,因为我需要在函数调用之间保存数据。我尝试了std::tr1::bindboost::bind,但它们返回的是函数对象,而不是指针,正如我所见,它不能“强制转换”为纯函数指针。而函数签名 (SetupIterateCabinet) 恰好需要一个纯 func 指针。

我需要如何解决问题的建议。谢谢。

【问题讨论】:

标签: c++ bind functor


【解决方案1】:

您不能将std::function 转换为函数指针(您可以做相反的事情)。您应该使用函数指针或std::functions。如果您可以使用std::function 代替指针,那么您应该这样做。

这使您的代码工作:

typedef function<void(void)> fp;

【讨论】:

  • 我唯一要补充的是,使用 std::function 还允许您使用重载运算符 () 的类型。很好的答案。
  • 你建议他如何改变SetupIterateCabinet(一个C API)来获取一个C++对象?
  • @ildjarn “您应该使用函数指针或 std::function”。如果他不能使用std::function,那么他应该使用函数指针,除非他想将他的std::functions 包裹在静态函数周围,但这不会很漂亮。
  • @ildjarn 你不能,他没有说别的。在这些情况下,我通常有一个包装器纯 C 函数,它使用最常传递给回调的“用户上下文”(SetupIterateCabinet 也提供一个)将回调路由到某些 C++ 事物。
  • @fontanini:那么,有没有办法传递有状态的对象?
【解决方案2】:

您大大简化了您的真正问题,并将您的问题变成了XY problem。让我们回到您的真正问题:如何使用非静态成员函数作为回调调用SetupIterateCabinet

给定一些类:

class MyClass
{
public:
    UINT MyCallback(UINT Notification, UINT_PTR Param1, UINT_PTR Param2)
    {
        /* impl */
    }
};

为了使用MyClass::MyCallback 作为SetupIterateCabinet 的第三个参数,您需要为Context 参数传递一个MyClass*,并使用一个普通的shim 函数来获取该Context 参数并做正确的事有它的东西:

UINT MyClassCallback(PVOID Context, UINT Notification, UINT_PTR Param1, UINT_PTR Param2)
{
    return static_cast<MyClass*>(Context)->MyCallback(Notification, Param1, Param2);
}

int main()
{
    MyClass mc;
    SetupIterateCabinet(_T("some path"), 0, MyClassCallback, &mc);
}

【讨论】:

    猜你喜欢
    • 2015-03-09
    • 2011-06-13
    • 2021-12-22
    • 1970-01-01
    • 2017-08-27
    • 1970-01-01
    • 2013-05-07
    • 1970-01-01
    • 2014-02-11
    相关资源
    最近更新 更多