Я знаю, что это ужасная идея изменить ключ объекта в ассоциативном контейнере, но мне интересно, где именно стандарт запрещает мне это делать. Рассмотрим:Почему бы не изменить ключ ассоциативного контейнера?
#include <map>
#include <memory>
struct X { int i; };
struct lt
{
bool operator()(const std::shared_ptr<X>& lhs,
const std::shared_ptr<X>& rhs) const
{
return lhs->i < rhs->i;
}
};
int main()
{
std::map< std::shared_ptr<X>, int, lt > m;
auto x = std::make_shared<X>();
x->i = 1;
m.insert(std::make_pair(x, 2));
x->i = 42; // change key wrt the container!
}
Я полагаю, что выше должно быть незаконным, но я читал стандарт в течение некоторого времени, и я не могу найти ничего, что на самом деле делает незаконным. Где это? Или он скрывается в будущем отчете о дефектах?
std :: map имеет внутреннее строение дерева. Если вы измените ключ, внутренняя структура неверна, и поиск не будет работать, потому что вы пойдете по неправильному пути. – Felics
@ Феликс: Это был не вопрос. –
В «Эффективном STL» С. Майерса есть целая глава именно по этой проблеме (см. Пункт 22). Самое смешное в том, что, хотя довольно сложно разрушить внутреннюю структуру карты (поскольку тип элемента карты - «пара')), вам придется использовать для этого какое-то псевдонимы - очень легко обмануть набор и мультимножество, потому что вы можете назначить '* it', когда' it' является (multi) set :: iterator. –
shakurov