wake-up-neo.com

Vergleich von std :: -Funktionen auf Gleichheit?

Wie kann ich zwei C++ 11 std::functions mit operator== vergleichen und true zurückgeben, wenn beide functions auf denselben Funktionszeiger verweisen?

28
JesseTG

operator == for std :: function vergleicht eine std :: function mit einem Nullzeiger, soweit ich feststellen kann, dass der Standard keine genauen Angaben dazu enthält.

Obwohl dieser boost FAQ -Eintrag Warum kann ich boost :: function-Objekte nicht mit operator == oder operator! =?) Vergleichen?? Liefert eine Begründung und soweit ich das beurteilen kann, sollte dies zutreffend sein zu std :: function . Zitieren der FAQ:

Der Vergleich zwischen boost :: Funktionsobjekten kann nicht "gut" implementiert werden und wird daher nicht implementiert. [...]

dann umreißt er angeforderte Lösungen ähnlich wie Preet und fährt fort zu sagen:

Das Problem tritt auf, wenn der Typ der von f und g gespeicherten Funktionsobjekte keinen Operator hat == [...]

und erklärt, warum dies entweder im Zuweisungsoperator oder Konstruktor behandelt werden muss und dann sagt:

Alle diese Probleme werden in Fehlern in den boost :: -Funktionskonstruktoren oder im Zuweisungsoperator umgewandelt, auch wenn der Benutzer niemals den Operator == aufruft. Das können wir den Benutzern nicht antun.

Aktualisieren

In Zugriff auf das Ziel eines tr1 :: -Funktionsobjekts wurde ein Standardgrund gefunden, der zwar ziemlich alt ist, aber mit dem Boost FAQ übereinstimmt, und sagt:

operator == ist für die tr1 :: -Funktion innerhalb der C++ - Sprache nicht implementierbar, da wir nicht zuverlässig feststellen können, ob ein bestimmter Typ T ohne Benutzerunterstützung Equality Comparable ist.

15
Shafik Yaghmour

Sie können es tatsächlich mit .target arbeiten lassen:

template<typename T, typename... U>
size_t getAddress(std::function<T(U...)> f) {
    typedef T(fnType)(U...);
    fnType ** fnPointer = f.template target<fnType*>();
    return (size_t) *fnPointer;
}

if (getAddress(f) == getAddress(g)) {...}

(Ref: C++ versucht, die Funktionsadresse von einer std :: function zu erhalten)

13
P i

Sie können versuchen, a und b zunächst zu vergleichen, indem Sie deren .target_type() vergleichen. Wenn diese Zieltyp-IDs identisch sind, können Sie deren .target() - Zeiger vergleichen. Sie können einen nicht übereinstimmenden Zieltyp als Early Out-False verwenden.

6
Preet Kukreti

Beachten Sie, dass die Gleichheit von Funktionen (die Entscheidung, ob zwei Funktionen immer dasselbe beobachtbare Verhalten haben) ein unentscheidbares Problem in der Lambda-Berechnung ist (und deshalb verbieten viele Programmiersprachen das Vergleichen von Funktionen).

Selbst wenn der ==-Test kompiliert wird, würde er höchstens testen, ob der Code identisch ist (die gleiche Adresse hat), nicht dass die verglichenen Funktionen dasselbe Verhalten aufweisen.

Wenn std::function<T(U...)> f eine Member-Funktion ist, ist fnPointer null.

1
yksten