¿Por qué es set :: find no una plantilla?

Con funciones de plantilla desde<algorithm> puedes hacer cosas como esta

struct foo
{
    int bar, baz;
};

struct bar_less
{
    // compare foo with foo
    bool operator()(const foo& lh, const foo& rh) const
    {
        return lh.bar < rh.bar;
    }
    template<typename T>  // compare some T with foo
    bool operator()(T lh, const foo& rh) const
    {
        return lh < rh.bar;
    }
    template<typename T>  // compare foo with some T
    bool operator()(const foo& lh, T rh) const
    {
        return lh.bar < rh;
    }
};

int main()
{
    foo foos[] = { {1, 2}, {2, 3}, {4, 5} };
    bar_less cmp;
    int bar_value = 2;
    // find element {2, 3} using an int
    auto it = std::lower_bound(begin(foos), end(foos), bar_value, cmp);
    std::cout << it->baz;
}

Enstd::set métodos comofind tienes que pasar un objeto de tiposet::key_type que a menudo te obliga a crear un objeto ficticio.

set<foo> foos;
foo search_dummy = {2,3};  // don't need a full foo object;
auto it = foos.find(search_dummy);

Sería tan útil si uno puede llamar simplementefoos.find(2). ¿Hay alguna razón por la cualfind no puede ser una plantilla, aceptando todo lo que se puede pasar al predicado menos. Y si solo falta, ¿por qué no está en C ++ 11 (creo que no lo está)?

Editar

La pregunta principal es POR QUÉ no es posible y, si fuera posible, POR QUÉ decidió la norma de no proporcionarla. Una segunda pregunta puede proponer soluciones :-) (boost::multi_index_container Recorre mi mente ahora mismo, que proporciona la extracción de claves de los tipos de valor)

Otro ejemplo con un tipo de valor más caro de construir. La clavename es parte del tipo y no debe utilizarse como una copia en la clave de mapas;

struct Person
{
    std::string name;
    std::string adress;
    std::string phone, email, fax, stackoferflowNickname;
    int age;
    std::vector<Person*> friends;
    std::vector<Relation> relations;
};

struct PersonOrder
{
    // assume that the full name is an unique identifier
    bool operator()(const Person& lh, const Person& rh) const
    {
        return lh.name < rh.name;
    }
};

class PersonRepository
{
public:

    const Person& FindPerson(const std::string& name) const
    {
        Person searchDummy;  // ouch
        searchDummy.name = name;
        return FindPerson(searchDummy);
    }

    const Person& FindPerson(const Person& person) const;

private:
    std::set<Person, PersonOrder> persons_;
    // what i want to avoid
    // std::map<std::string, Person> persons_;
    // Person searchDummyForReuseButNotThreadSafe;

};

Respuestas a la pregunta(5)

Su respuesta a la pregunta