понизьте в должности повышение:: функционируйте к простому указателю функции

Я предлагаю вам проверить Tippy.js , это классная библиотека всплывающих подсказок и всплывающих окон, она очень настраиваема.

21
задан Dustin Getz 11 November 2008 в 22:39
поделиться

5 ответов

Кто-нибудь заметил, что принятый ответ работает только с тривиальными случаями? Единственный способ, которым функция <> :: target () вернет объект, который может быть привязан к обратному вызову C, - это если он был построен с объектом, который может быть привязан к обратному вызову C. Если это так, то вы могли бы связать его напрямую и для начала пропустить всю ерунду function <>.

Если задуматься, тут нет никакого волшебного решения. Обратный вызов в стиле C хранится как единственный указатель, указывающий на исполняемый код. Для любого нетривиального boost :: function <> потребуется как минимум два указателя: один на исполняемый код, другой на данные, необходимые для настройки вызова (например, указатель this в случае связанного члена функция).

Правильный способ использования boost :: function и boost :: bind с обратными вызовами C - это создать функцию-прокладку, которая удовлетворяет сигнатуре обратного вызова, определяет, какую функцию <> вызывать, и вызывает ее. Обычно обратные вызовы C имеют некоторую пустоту * для «пользовательских данных»; это место, где вы прячете указатель на функцию:

typedef void (*CallbackType)(int x, void* user_data);
void RegisterCallback(CallbackType cb, void* user_data);

void MyCallback(int x, void* userData) {
  boost::function<void(int)> pfn = static_cast<boost::function<void(int)> >(userData);
  pfn(x);
}

boost::function<void(int)> fn = boost::bind(myFunction(5));
RegisterCallback(MyCallback, &fn);

Конечно, если ваша подпись обратного вызова не включает какой-либо указатель на данные пользователя, вам не повезло. Но любой обратный вызов, который не включает указатель пользовательских данных, уже непригоден для использования в большинстве реальных сценариев и должен быть переписан.

41
ответ дан 29 November 2019 в 06:44
поделиться

можно ли добраться, это работающий со связывает?

cb_t cb = *g.target<cb_t>(); //target returns null

Это дизайном . В основном, с тех пор bind возвраты совершенно другой тип, нет никакого способа, которым это будет работать. В основном объект прокси редактора связей не может быть преобразован в указатель функции C (так как это не то: это - функциональный объект). Тип, возвращенный boost::bind, является сложным. Текущий стандарт C++ не позволяет никакому хорошему способу сделать то, что Вы хотите. C++ 0x будет оснащен decltype выражение, которое могло использоваться здесь для достижения чего-то вроде этого:

typedef decltype(bind(f, 3)) bind_t;
bind_t target = *g.target<bind_t>();

Уведомление, которое этот могло бы или не могло бы работать. У меня нет способа протестировать его.

3
ответ дан 29 November 2019 в 06:44
поделиться
2
ответ дан 29 November 2019 в 06:44
поделиться

можно ли добраться, это работающий со связывает?

#include <boost/function.hpp>
#include <boost/bind.hpp>

void f(int x)
{
    (void) x;
    _asm int 3;
}

typedef void (*cb_t)(int);

int main()
{
    boost::function<void (int x)> g = boost::bind(f, 3);
    cb_t cb = *g.target<cb_t>(); //target returns null
    cb(1);

    return 0;
}

обновление: Хорошо, хорошо намерение состоит в том, чтобы связать метод в функциональный обратный вызов. таким образом, теперь, что?

0
ответ дан 29 November 2019 в 06:44
поделиться

Я думаю, что Вы хотите использовать цель () функция членства повышения:: функция (не то, что полный рот...)

#include <boost/function.hpp>
#include <iostream>

int f(int x)
{
  return x + x;
}

typedef int (*pointer_to_func)(int);

int
main()
{
  boost::function<int(int x)> g(f);

  if(*g.target<pointer_to_func>() == f) {
    std::cout << "g contains f" << std::endl;
  } else {
    std::cout << "g does not contain f" << std::endl;
  }

  return 0;
}
11
ответ дан 29 November 2019 в 06:44
поделиться
Другие вопросы по тегам:

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