Сравнение std :: function <> - PullRequest
6 голосов
/ 01 мая 2011

Можно ли как-то сравнить два std::tr1::function<> объекта?Что если у меня есть коллекция function<void(int,float)> объектов и я хочу добавить и удалить обработчики событий?Добавление тривиально, но найти тот, который нужно удалить, кажется невозможным.

Ответы [ 2 ]

7 голосов
/ 01 мая 2011

Не может быть сделано, проще говоря.std::function (во всех его итерациях, включая boost::function и std::tr1::function) не поддерживает operator==.

3 голосов
/ 25 сентября 2013

Основываясь на информации из переполнения стека по следующей ссылке, это возможно, но только если вы оберните объект std :: function в его собственный класс.

std :: vector из std :: function

Используя класс-оболочку, вы можете проверить, равны ли два указателя обернутых std :: function, но это не так.ничего не скажу о том, что оборачивает функция std ::.Таким образом, изменение вашего дизайна, вероятно, является лучшим подходом.

edit: я вернулся, чтобы показать, как я решил очень похожую проблему.

0) Typedefs для краткости.

    using std::placeholders;
    typedef std::function < void ( int, float ) > some_func;
    typedef std::pair < intptr_t, intptr_t > method_hash;
  1. Напишите свою коллекцию объектов std :: function, привязав указатели к методам или функциям.Там, где вы делаете это для статических функций, опустите some_object_ptr.

    some_func some_method ( std::bind ( some_method_ptr, 
                                        some_object_ptr, _1, _2 ) 
    
  2. Используйте std :: reinterpret_cast , чтобы создать уникальный хеш для вашей функции, и используйте его с std:: pair для методов.

     method_hash pairID ( reinterpret_cast < intptr_t > ( some_object_ptr ), 
                          reinterpret_cast < intptr_t > ( some_method_ptr ) );
    
  3. Теперь ваш pairID может храниться в векторе или другом контейнере / массиве.Просто убедитесь, что индексы выровнены так, что хеш всегда соответствует правильному объекту std :: function, и затем вы можете использовать find (), чтобы получить итератор в его позицию, и distance (), чтобы преобразовать итератор втребуемый индекс.

Обратите внимание, что это нужно будет делать каждый раз при создании контейнера.Поскольку он основан на указателях, хэши будут меняться при разных запусках вашей программы.

...