Warum ist set :: find keine Vorlage?

Mit Template-Funktionen von<algorithm> Sie können solche Dinge tun

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

Imstd::set Methoden wiefind Sie müssen ein Objekt vom Typ übergebenset::key_type Das zwingt Sie oft, ein Dummy-Objekt zu erstellen.

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

Es wäre so hilfreich, wenn man eben anrufen kannfoos.find(2). Gibt es einen Grund dafür?find Es kann keine Vorlage sein, die alles akzeptiert, was an das weniger wichtige Prädikat übergeben werden kann. Und wenn es nur fehlt, warum ist es nicht in C ++ 11 (glaube ich nicht).

Bearbeiten

Die Hauptfrage ist, WARUM es nicht möglich ist und wenn es möglich ist, WARUM der Standard beschlossen hat, es nicht bereitzustellen. Als zweite Frage kannst du Workarounds vorschlagen :-) (boost::multi_index_container fällt mir gerade ein, was eine Schlüsselextraktion aus Werttypen bietet)

Ein weiteres Beispiel mit einem teurer zu konstruierenden Wertetyp. Der Schlüsselname ist Teil des Typs und sollte nicht als Kopie in Maps Key verwendet werden.

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;

};

Antworten auf die Frage(5)

Ihre Antwort auf die Frage