Say chcesz zapisać następujące:wektora std :: funkcji <>
typedef std::function<void(int)> MyFunctionDecl;
..w kolekcji:
typedef std::vector<MyFunctionDecl> FunctionVector;
FunctionVector v;
Jest to możliwe, ale jeśli chcę znaleźć coś za pomocą std::find
:
FunctionVector::const_iterator cit = std::find(v.begin(), v.end(), myFunctionDecl);
.. my się błąd ze względu na operatora ==
.
Jak sugerowano mi w poprzednim pytaniu dotyczącym tego, to można zdobyć wokół przez umieszczenie deklaracji funkcji wewnątrz innej klasy, który zapewnia ==
operatora:
class Wrapper
{
private:
MyFunctionDecl m_Func;
public:
// ctor omitted for brevity
bool operator == (const Wrapper& _rhs)
{
// are they equal?
}; // eo ==
}; // eo class Wrapper
Więc co chcę zrobić w jakiś sposób generuje skrót dla "MyFunctionDecl", dzięki czemu mogę poprawnie zaimplementować operatora ==
. Mógłbym mieć jakiś unikalny identyfikator i poprosić rozmówcę o podanie unikalnego identyfikatora dla delegata, ale wydaje się to być trochę uciążliwe i podatne na błędy.
Czy istnieje sposób, że mogę to zrobić? Aby te same funkcje zwracały ten sam identyfikator do celów porównawczych? Do tej pory jedynym sposobem na to jest zrzucenie pojęcia o użyciu std::function
i powrót do korzystania z szybkich delegatów, które obsługują porównania. Ale potem tracę zdolność używania lambdas.
Każda pomoc doceniona!
EDIT
Biorąc pod uwagę poniżej odpowiedź, to co mam wymyślić ... żadnych zastrzeżeń mógłbym przegapić? Jestem w procesie wprowadzenie go poprzez jego kroków teraz:
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
Dlaczego musisz znaleźć?Jeśli potrzebujesz znaleźć taką funkcję std ::, musisz ją znaleźć na podstawie jakiegoś identyfikatora lub podobnego, powiedzmy automatycznie wygenerowanego int dla każdego tworzonego Wrappera. Znajdź int dla przyszłego porównania i upewnij się, że tworzysz tylko jedno opakowanie. – villintehaspam
Nie można porównywać funkcji, jest to * problem z zatrzymaniem * (http://en.wikipedia.org/wiki/Halting_problem) –
@Alexandre Myślę, że problem zatrzymania jest powiązany, ale zdecydowanie nie jest taki sam. Myślę, że pomysł hasha jest taki, że nie trzeba uruchamiać tej funkcji, aby ją porównać. –