Вопрос по c++, bind, functor – std :: function -> указатель на функцию

10

Вот код:

<code>#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
}
</code>

Первоначально мне нужно сделать указатель на функцию из нестатического метода класса, потому что мне нужно сохранять данные между вызовами функций. Я пыталсяstd::tr1::bind а такжеboost::bind, но они возвращают функциональный объект, а не указатель, который, как я вижу, не может быть «приведен» к чисто функциональному указателю. Пока функция подпись SetupIterateCabinet) точно требует чистый указатель на функцию.

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

Ваш Ответ

2   ответа
8

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

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

typedef function<void(void)> fp;
Как ты предлагаешь ему поменятьSetupIterateCabinet (API C), чтобы взять объект C ++? ildjarn
Единственное, что я добавлю, это то, что использование std :: function также позволяет вам использовать тип с перегруженным operator (). Отличный ответ. Stephen Newell
@ ildjarn "Вы должны использовать либо указатели функций, либоstd::function ". Если он не может использоватьstd::function тогда он должен использовать функциональные указатели, если только он не хочет обернуть егоstd::function вокруг статических функций, но это не будет красиво. mfontanini
@ fontanini: То есть нет способа передать объект, имеющий состояние? fogbit
@ ildjarn, ты не можешь, и он больше ничего не сказал. В этих случаях у меня обычно есть обычная C-функция-обертка, которая с помощью «пользовательского контекста» чаще всего передается обратным вызовам (SetupIterateCabinet также предлагает один) для маршрутизации обратного вызова к некоторому C + zerm
7

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

Дай какой-нибудь класс:

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

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

Похожие вопросы