¿Por qué std :: function no es igualdad comparable?

Esta pregunta también se aplica aboost::function ystd::tr1::function.

std::function no es la igualdad 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, eloperator== yoperator!= las sobrecargas simplemente no existen. En un borrador inicial de C ++ 11, las sobrecargas se declararon como eliminadas con el comentario (N3092 §20.8.14.2):

// deleted overloads close possible hole in the type system

No dice cuál es el "posible agujero en el sistema de tipos". En TR1 y Boost, las sobrecargas se declaran pero no se definen. Los comentarios de la especificación TR1 (N1836 §3.7.2.6):

Estas funciones miembro se dejarán sin definir.

[Nota: la conversión de tipo booleano abre un vacío legal mediante el cual se pueden comparar dos instancias de funciones mediante== o!=. Estos indefinidosvoid los operadores cierran la escapatoria y aseguran un error en tiempo de compilación.—Nota final]

Mi comprensión del "vacío legal" es que si tenemos unbool función de conversión, esa conversión puede usarse en comparaciones de igualdad (y en otras circunstancias):

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!
}

Tenía la impresión de que se usaba el modismo safe-bool en C ++ 03 y el uso de una función de conversión explícita en C ++ 11 para evitar este "vacío". Boost y TR1 usan el modismo safe-bool enfunction y C ++ 11 hace que elbool Función de conversión explícita.

Como ejemplo de una clase que tiene ambos,std::shared_ptr ambos tienen un explícitobool función de conversión y es igualdad comparable.

Por que esstd::function no igualdad comparable? ¿Cuál es el "posible agujero en el sistema de tipos"? ¿Cómo es diferente destd::shared_ptr?

Respuestas a la pregunta(8)

Su respuesta a la pregunta