Не понимаю, почему
inline bool operator<(const Thing& a,const Thing& b) {
return (a.index<b.index);
}
std::set<Thing> things; // Uses comparison operator above
Thing &thing3 = *things.find(Thing(3));
делает не совсем то, что вы хотите.Отсутствие дублирования / копирования индексного поля и сравнение ключей так же эффективно, как и при использовании карты;что не нравится?
Обновление в свете комментариев ниже:
Если вещь настолько тяжелая, что вы не хотите ее копировать, то вам, вероятно,в итоге получится код, подобный следующему:
inline bool operator<(const shared_ptr<Thing>& a,const shared_ptr<Thing>& b) {
return (a->index < b->index);
}
std::set<shared_ptr<Thing>> things; // Uses comparison operator above
shared_ptr<Thing> key3(new Thing(3));
Thing &thing3 = *things.find(key3);
, хотя сравнение значений указателей с ИМХО довольно вредно, и было бы лучше пойти более подробным путем явного аргумента «Сравнить» к заданным аргументам шаблона.
Следует иметь в виду одну вещь (из моего собственного опыта с очередями с большим приоритетом для тяжеловесных объектов): у контейнеров на основе std::pair<trivial_key,shared_ptr<heavyweight_object>>
могут быть существенные преимущества перед std::pair<trivial_key,heavyweight_object>
из-за того, что обходыпервое касание только клавиш (например, find
) может быть намного более эффективным кешированием по сравнению с последним, которое также извлекает в кэш-память большое количество ненужных / не относящихся к делу heavyweight_object
байт (зависит от деталей и чиселконечно, но на самом деле этот эффект может легко затопить относительно небольшие затраты на дублирование ключа).