Say möchte folgendes speichern:Vector von std :: function <>
typedef std::function<void(int)> MyFunctionDecl;
..in einer Sammlung:
typedef std::vector<MyFunctionDecl> FunctionVector;
FunctionVector v;
Dies ist möglich, aber wenn ich willfinden etwas mit std::find
:
FunctionVector::const_iterator cit = std::find(v.begin(), v.end(), myFunctionDecl);
.. wir bekommen einen Fehler aufgrund der ==
Betreiber.
Wie mir in einer früheren Frage nach dieser vorgeschlagen worden ist, kann diese um innerhalb einer anderen Klasse durch Einkapseln der Funktionsdeklaration werden erhalten, die einen ==
Operator bietet:
class Wrapper
{
private:
MyFunctionDecl m_Func;
public:
// ctor omitted for brevity
bool operator == (const Wrapper& _rhs)
{
// are they equal?
}; // eo ==
}; // eo class Wrapper
Also, was ich tun möchte, erzeugt irgendwie einen Hash für "MyFunctionDecl", so dass ich den ==
Operator richtig implementieren kann. Ich könnte eine Art eindeutiger Bezeichner haben und den Anrufer bitten, eine eindeutige Kennung für den Beauftragten anzugeben, aber das scheint ein bisschen mühsam und fehleranfällig zu sein.
Gibt es eine Möglichkeit, dass ich das tun kann? Damit dieselben Funktionen die gleiche ID für Vergleichszwecke liefern? Bis jetzt ist der einzige Weg, um den Begriff der Verwendung von std::function
zu verlassen und wieder schnell Delegaten verwenden, die Vergleiche unterstützen. Aber dann verliere ich die Fähigkeit, Lambdas zu verwenden.
Jede Hilfe wird geschätzt!
EDIT
die Antwort Da unten, das ist, was ich mit ... irgendwelchen Einschränkungen kommen habe ich verpasst haben könnte? Ich bin in den Prozess es durch sie die Schritte jetzt setzen:
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
Warum müssen Sie suchen?Wenn Sie eine std :: -Funktion wie diese finden müssen, müssen Sie sie anhand eines Bezeichners oder ähnlichem suchen, z. B. ein automatisch generiertes int für jeden neuen Wrapper, den Sie erstellen. Holen Sie sich den int für den zukünftigen Vergleich und stellen Sie sicher, dass Sie nur jeden Wrapper einmal erstellen. – villintehaspam
Sie können keine Funktionen vergleichen, dies ist das * Halteproblem * (http://en.wikipedia.org/wiki/Halting_problem) –
@Alexandre Ich denke, das Anhalten Problem ist verwandt, aber definitiv nicht das Gleiche. Ich würde denken, dass die Idee des Hash ist, dass Sie die Funktion nicht ausführen müssen, um es zu vergleichen. –