Получить адрес функции-члена через std :: bind? - PullRequest
0 голосов
/ 20 февраля 2019
size_t getAddress(F f) {
    typedef void (fnType)(Ts...);
    fnType ** fnPointer = f.template target<fnType*>();
    if (fnPointer == nullptr) { //Must be member function.
        //Code to get address of member function pointer
    }
    return (size_t)*fnPointer;
}

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

Я думаю, это потому, что я шаблонирую указатель функции как тип моего обычного указателя функции.Но со связанной функцией-членом через std :: bind это преобразование завершается неудачей.

Я использую это в своем операторе сравнения для поиска и удаления функций из вектора.

EventObject<Ts...>& operator-=(const F& rhs) {
    int i = 0;
    for (auto const& value : callbacks) {
        if (getAddress(rhs) == getAddress(value)) {
            erase(i);
            break;
        }
        i++;
    }
    return *this;
}

Google не удалось мне,Я также представляю, что эта функция будет работать для лямбда-сорта.Пока компилятор пытается оптимизировать и комбинировать подобные лямбда-выражения.

Итак, как мне получить адрес указателя на функцию-член через bind?Или есть более оптимальный способ?(Кроме именования) Возможно, стоит ли обернуть мою функцию в макрос, чтобы вместо этого хранить перечислимый тип для сравнения?

Информация о классе для справки:

template <typename...Ts>
class EventObject{
public:
    typedef std::function<void(Ts...)> F;
    typedef std::vector<F> CallBack;
    Callback callbacks;

1 Ответ

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

Вместо этого следует перейти на использование std::function (обновление: оказывается, вы уже сделали).std::function - это обертка полиморфной функции общего назначения, которая будет принимать необработанные указатели функций, привязки и т. Д. Таким образом, у вас есть стандартизированный способ сравнения, который вам нужно каким-то образом осуществить, но у std::function есть способы проверки цели,и т. д .: https://en.cppreference.com/w/cpp/utility/functional/function

Ваша подпись становится:

EventObject<Ts...>& operator-=(const std::function<R(Args...)>& rhs) {

Обновление: проблема с целевым извлечением заключается в том, что вы предоставляете подпись простой функции какаргумент шаблона - это не будет работать для более «продвинутых» функциональных объектов, привязок и т. д. Вы должны предоставить правильный тип так:

target_type () == typeid (T)

см. https://en.cppreference.com/w/cpp/utility/functional/function/target для получения дополнительной информации и некоторые соответствующие примеры

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...