Por que std :: function não é comparável à igualdade?

Esta pergunta também se aplica aboost::function estd::tr1::function.

std::function não é uma igualdade comparável:

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

No C ++ 11, ooperator== eoperator!= sobrecargas simplesmente não existem. Em um rascunho inicial do C ++ 11, as sobrecargas foram declaradas como excluídas com o comentário (N3092 §20.8.14.2):

// deleted overloads close possible hole in the type system

Não diz qual é o "possível buraco no sistema de tipos". No TR1 e no Boost, as sobrecargas são declaradas, mas não definidas. Os comentários da especificação TR1 (N1836 §3.7.2.6):

Essas funções de membro devem ser deixadas indefinidas.

[Nota: a conversão do tipo booleano abre uma brecha na qual duas instâncias de função podem ser comparadas via== ou!=. Estes indefinidosvoid operadores fecham a brecha e garantem um erro em tempo de compilação.- end note]

Meu entendimento da "brecha" é que, se tivermos umbool função de conversão, essa conversão pode ser usada em comparações de igualdade (e em outras circunstâncias):

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

Fiquei com a impressão de que o idioma safe-bool no C ++ 03 e o uso de uma função de conversão explícita no C ++ 11 foram usados para evitar essa "brecha". O Boost e o TR1 usam o idioma safe-bool nofunction e C ++ 11 torna obool função de conversão explícita.

Como exemplo de uma classe que possui ambos,std::shared_ptr ambos tem um explícitobool função de conversão e é comparável à igualdade.

Porque éstd::function igualdade não é comparável? Qual é o "buraco possível no sistema de tipos?" Como é diferente destd::shared_ptr?

questionAnswers(8)

yourAnswerToTheQuestion