Vector von std::function<>

Sagen wollen, speichern Sie den folgenden:

typedef std::function<void(int)> MyFunctionDecl;

... in einer Sammlung:

typedef std::vector<MyFunctionDecl> FunctionVector;
FunctionVector v;

Dies ist möglich, aber wenn ich will finden etwas mit std::find:

FunctionVector::const_iterator cit = std::find(v.begin(), v.end(), myFunctionDecl);

.. wir bekommen eine Fehlermeldung wegen der == Betreiber.

Da wurde mir vorgeschlagen, in einer vorherigen Frage in Bezug auf diese, können Sie dies bekommen, um durch die Kapselung der Deklaration der Funktion innerhalb einer anderen Klasse, die eine == Betreiber:

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, ist irgendwie generieren einen hash für "MyFunctionDecl", so dass ich richtig implementieren die == Betreiber. Ich könnte irgendeine Art von eindeutigen Bezeichner, und bitten Sie den Anrufer, um eine eindeutige Kennung für das delegieren, aber das scheint ein bisschen wie ein Schmerz und ist fehleranfällig.

Gibt es eine Möglichkeit, dass ich dies tun kann? So dass die gleichen Funktionen liefern die gleiche ID für vergleichende Zwecke? So weit, der einzige Weg, um es zu dumpen Vorstellung mit std::function und gehen Sie zurück zu schnell Delegierten die Unterstützung Vergleiche. Aber dann verliere ich die Fähigkeit zur Nutzung von lambdas.

Jede Hilfe dankbar!

BEARBEITEN

Gegeben, die Antwort unten, das ist, was ich mit kommen... alle Vorbehalte, die ich verpasst haben könnte? Ich bin in den Prozess der Umsetzung durch die Schritte jetzt:

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 zu finden? Wenn Sie brauchen, um zu finden, ein std::function wie diese, werden Sie brauchen, um es zu finden basiert auf eine id oder ähnliches, sagen wir eine automatisch generierte int für jede neue Wrapper, die Sie erstellen. Holen Sie sich die int für die Zukunft-Vergleich und stellen Sie sicher, dass Sie nur erstellen, jeden wrapper einmal.
  • Sie vergleichen nicht funktioniert, das ist das Halteproblem (en.wikipedia.org/wiki/Halting_problem )
  • Ich denke, dass das Halteproblem ist verwandt, aber definitiv nicht das gleiche. Ich würde denken, dass die Idee der hash ist, dass Sie nicht brauchen, um ausführen die Funktion zu vergleichen.
  • Hinzufügen und überarbeiten, ist kein problem. Allerdings, möchten, erstellen Sie eine Ereignis-Typ-Klasse, die es erlaubt, mehrere Delegierte werden gespeichert und, wenn Sie wollen, sich zu entfernen auch. Denken addListener und removeListener als Schnittstelle, um diese Art der Sache.
  • in diesem Fall sind Sie nie gehen, um zu der Erzeugung neuer Wrapper für die gleiche Funktion wieder und so mit Hilfe von ints wie in meinem Kommentar oben gut funktionieren wird. Nur machen addListener return die eindeutige id und lassen removeListener nehmen, dass als ein argument.
  • Verwandte: Vergleich von std::tr1::function<> Objekte
  • Warum müssen Sie zu finden, die Funktion, die Sie bereits haben? o_O
  • Sie wollen also zu-tag jede Funktion in einer Sammlung? Warum nicht verwenden eine std::map für Sie, dass anstelle von std::vector dann?
  • Ich denke, Sie sollten sich auf die boost Bibliothek... ich glaube, alrdy implementiert, was Sie zu tun versuchen.

InformationsquelleAutor Moo-Juice | 2011-01-03
Schreibe einen Kommentar