Почему set :: find не шаблон?
С шаблонными функциями из<algorithm>
ты можешь делать такие вещи
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;
}
Вstd::set
методы, такие какfind
Вы должны передать объект типаset::key_type
что часто заставляет вас создавать фиктивный объект.
set<foo> foos;
foo search_dummy = {2,3}; // don't need a full foo object;
auto it = foos.find(search_dummy);
Было бы очень полезно, если бы можно было просто позвонитьfoos.find(2)
, Есть ли причина, почемуfind
не может быть шаблоном, принимающим все, что может быть передано меньшему предикату. И если это просто отсутствует, почему это не в C ++ 11 (я думаю, что это не так).
Основной вопрос: ПОЧЕМУ это невозможно, и если это было возможно, ПОЧЕМУ решил, что стандарт не предусматривает этого? А второй вопрос вы можете предложить обходные пути :-) (boost::multi_index_container
только что пришло мне в голову, что обеспечивает извлечение ключей из типов значений)
Другой пример с более дорогим для построения типом значения. Ключname
является частью типа и не должен использоваться в качестве копии в ключе карты;
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;
};