Std:: function → указатель функции

Вот код:

#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::bind и boost::bind, но они возвращают функциональный объект, а не указатель, который, как я вижу, не может быть "отлит" от чистого функционального указателя. Хотя сигнатура функции (SetupIterateCabinet) требует чистого указателя func.

Мне нужно посоветовать, как решить проблему. Спасибо.

Ответ 1

Вы значительно упростили свою реальную проблему и превратили свой вопрос в проблему XY. Вернемся к вашему реальному вопросу: как вызвать SetupIterateCabinet с нестатической функцией-членом в качестве обратного вызова.

Для некоторого класса:

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

Чтобы использовать MyClass::MyCallback в качестве третьего аргумента для SetupIterateCabinet, вам нужно передать MyClass* для аргумента Context и использовать простую функцию прокладки, чтобы принять этот аргумент 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);
}

Ответ 2

Вы не можете преобразовать std::function в указатель функции (вы можете сделать обратное). Вы должны использовать либо указатели функций, либо std::function s. Если вы можете использовать std::function вместо указателей, то вы должны.

Это заставляет ваш код работать:

typedef function<void(void)> fp;