C ++ передает перегруженный оператор () класса в качестве указателя на функцию - PullRequest
0 голосов
/ 12 февраля 2019

Так что я оказался на шатком основании, настаивая на том, чтобы класс C ++ имитировал обычную функцию.Класс перегружает оператор функции, что делает его функтором, конечно.Это все работает нормально, пока вы не захотите передать указатель на функцию этого функтора.

Естественно, я хочу сообщить компилятору, что мы знаем, что мы делаем (смеется), выполнив reinterpret_cast этогоуказатель.Тем не менее, как я могу получить адрес этой конкретной функции-члена, так как это перегруженный оператор.Как можно получить адрес этого?

ОБНОВЛЕНИЕ: Вы попросили пример.Вот минимальный.

Итак, у меня есть интерфейс, который я не могу изменить.Это выглядит так:

typedef void (*some_callback_t)(SomeType);'
void someFunc(some_callback_t);

Теперь это довольно просто;API устанавливает некоторый указатель на функцию обратного вызова.Итак, идея состояла в том, чтобы реализовать обратный вызов как класс функторов, перегружая operator(), как обычно, как обычно.

class Bah {
  void operator()(SomeType);
};

Здесь возникает вопрос;видя, что я не могу изменить используемый API (функция, которая ожидает указатель на функцию определенной сигнатуры), как я могу тогда получить адрес функции-члена и передать ее?

Я подозреваю, что это выглядит примерно так;someFunc(reinterpet_cast<some_callback_t>( ? ? ? )); чтобы убедиться, что компилятор не будет раздражать меня.

Ответы [ 2 ]

0 голосов
/ 12 февраля 2019

Предположим, что у вас есть для использования указателя функции, и что у вашего функтора нет состояния, вы можете использовать лямбду в качестве клея:

void takesFunctionPointer(void (*)());

struct MyFunctor {
    void operator()();
};

// ...

takesFunctionPointer([] { return MyFunctor{}(); });
0 голосов
/ 12 февраля 2019

Как получить адрес этого?

Таким же образом, как и любая другая функция-член.Название функции class_name::operator().Пример:

struct class_name {
    void operator()(){}
};

void (class_name::*member_function_pointer)() = &class_name::operator();
class_name instance;
(instance.*member_function_pointer)(); // in a block scope

Естественно, я хочу сообщить компилятору, что мы знаем, что мы делаем (смеется), выполнив reinterpret_cast этого указателя.

Обычно это не то, что хочется делать.

...