Pourquoi est std::function et non l'égalité comparable?

Cette question s'applique aussi à boost::function et std::tr1::function.

std::function n'est pas l'égalité comparable:

#include <functional>
void foo() { }

int main() {
    std::function<void()> f(foo), g(foo);
    bool are_equal(f == g); //Error:  f and g are not equality comparable
}

En C++11, le operator== et operator!= surcharges n'existent tout simplement pas. Dans un début de C++11 projet de, les surcharges ont été déclarés comme étant supprimés avec le commentaire (N3092 §20.8.14.2):

//deleted overloads close possible hole in the type system

Il ne dit pas ce que la possibilité "d'un trou dans le système de type" est. Dans TR1 et Boost, les surcharges sont déclarés mais non définis. Le TR1 spécification commentaires (N1836 §3.7.2.6):

Ces fonctions de membre doivent être laissés dans le vague.

[Remarque: la boolean-comme la conversion ouvre une faille qui fonction à deux instances peuvent être comparés par == ou !=. Ces undefined void opérateurs à proximité de la faille et de veiller à une erreur de compilation. —la note de fin de]

Ma compréhension de la "faille" est que si nous avons un bool fonction de conversion, la conversion peut être utilisé dans la comparaison d'égalité (et dans d'autres circonstances):

struct S {
    operator bool() { return false; }
};

int main() {
    S a, b;
    bool are_equal(a == b); //Uses operator bool on a and b!  Oh no!
}

J'étais sous l'impression que le coffre-bool idiome en C++03 et l'utilisation d'une conversion explicite de la fonction en C++11 a été utilisé pour éviter cette "lacune." De stimuler et de TR1 à la fois utiliser le coffre-bool idiome dans function et C++11 fait le bool fonction de conversion explicite.

Comme un exemple d'une classe qui a les deux, std::shared_ptr à la fois explicitement de bool de fonctions de conversion et d'égalité comparable.

Pourquoi est std::function pas l'égalité comparable? Qu'est-ce que la possibilité "d'un trou dans le type de système?" Comment est-il différent de std::shared_ptr?

  • Notez que vous pouvez demander pour * a.target< ftor_type >() == * b.target< ftor_type >() s'ils pointent vers l'égalité comparable à la foncteurs. Bien que ce soit un peu capricieux (l'objet sous-jacent va pas être implicitement converti dans le type demandé), il ne précise pas exactement dont la sémantique de comparaison sont utilisés.