Скажите, что хотите сохранить следующее:
typedef std::function<void(int)> MyFunctionDecl;
.. в коллекции:
typedef std::vector<MyFunctionDecl> FunctionVector;
FunctionVector v;
Это возможно, но если я хочу найти что-то, используя std::find
:
FunctionVector::const_iterator cit = std::find(v.begin(), v.end(), myFunctionDecl);
.. получаем ошибку из-за оператора ==
.
Как мне было предложено в предыдущем вопросе об этом, это можно получить, инкапсулируя объявление функции внутри другого класса, который предоставляет оператор ==
:
class Wrapper
{
private:
MyFunctionDecl m_Func;
public:
// ctor omitted for brevity
bool operator == (const Wrapper& _rhs)
{
// are they equal?
}; // eo ==
}; // eo class Wrapper
Так что я хочу сделать так, чтобы создать хэш для "MyFunctionDecl", чтобы я мог правильно реализовать оператор ==
. Я мог бы иметь какой-то уникальный идентификатор и попросить вызывающего абонента предоставить уникальный идентификатор для делегата, но это кажется немного больным и подвержено ошибкам.
Есть ли способ, которым я могу это сделать? Чтобы те же функции возвращали один и тот же идентификатор для сравнительных целей? До сих пор единственный способ обойти это - отказаться от понятия использования std::function
и вернуться к использованию быстрых делегатов, которые поддерживают сравнения. Но тогда я теряю способность использовать лямбды.
Любая помощь оценивается!
ИЗМЕНИТЬ
Учитывая приведенный ниже ответ, это то, что я придумал... любые предостережения, которые я, возможно, пропустил? Сейчас я пытаюсь выполнить его шаги:
class MORSE_API Event : boost::noncopyable
{
public:
typedef std::function<void(const EventArgs&)> DelegateType;
typedef boost::shared_ptr<DelegateType> DelegateDecl;
private:
typedef std::set<DelegateDecl> DelegateSet;
typedef DelegateSet::const_iterator DelegateSet_cit;
DelegateSet m_Delegates;
public:
Event()
{
}; // eo ctor
Event(Event&& _rhs) : m_Delegates(std::move(_rhs.m_Delegates))
{
}; // eo mtor
~Event()
{
}; // eo dtor
// methods
void invoke(const EventArgs& _args)
{
std::for_each(m_Delegates.begin(),
m_Delegates.end(),
[&_args](const DelegateDecl& _decl) { (*_decl)(_args); });
}; // eo invoke
DelegateDecl addListener(DelegateType f)
{
DelegateDecl ret(new DelegateType(f));
m_Delegates.insert(ret);
return ret;
}; // eo addListener
void removeListener(const DelegateDecl _decl)
{
DelegateSet_cit cit(m_Delegates.find(_decl));
if(cit != m_Delegates.end())
m_Delegates.erase(cit);
}; // eo removeListener
}; // eo class Event