multiset::find почему-то находит элементы с аргументом в виде только что созданного указателя
Разбираю старый код. Имеется контейнер std::multiset с указателями на структуру. Далее по коду после создания каждого указателя на структуру и заполнения её полей проверяется, нет ли в контейнере такого же указателя... Я считал, что такой код не нёс никакой смысловой нагрузки:
//Комменты на англ. писал не я
string16 header; // typedef char string16 [16];
str_value* sv = (str_value*)header; //str_value - та структура, на которую хранятся указатели
sv->dwReference = 0;
sv->dwLength = s_len;
sv->dwCRC = crc32(value,s_len); //Вычисление контрольной суммы, как я понял, уникальный идентификатор
//template <typename K, class P=std::less<K>, typename allocator = xalloc<K> > class xr_multiset : public std::multiset<K,P,allocator> {public: u32 size() const {return (u32)__super::size();}};
//typedef xr_multiset<str_value*,str_value_cmp> cdb;
//cdb container;
cdb::iterator I = container.find(sv); // only integer compares :)
if (I!=container.end())
{
// something found - verify, it is exactly our string
// Детали не важны
}
Казалось бы, как в контейнере можно найти совпадение с только что созданным указателем sv? Даже если у структуры по этому указателю целиком совпадают поля с некой структурой по находящемуся в контейнере указателю, у них адреса разные! Это разные объекты, и find никогда не должен срабатывать. Но нет, точка останова постоянно срабатывает внутри if (I!=container.end()). Ну я почитал, как сравниваются указатели (как я и знал, они равны, только если являются нулевыми или ссылаются на одно и то же), почитал, как работает multiset::find (простое сравнение аргумента с элементами, в данном случае указатель с указателями, и подозрение на функцию сравнения str_value_cmp отпало), и до сих пор ума не приложу, как это работает. Смысл комментария в коде
// only integer compares :)
я считал заблуждением, а теперь считаю магией. Помогите разобраться.
Ответы (2 шт):
Во-первых, на то и мультимножество, что оно может содержать одинаковые элементы!
А во-вторых, сравниваются значения с помощью компаратора, а как работает ваш компаратор str_value_cmp, из вопроса не ясно — а ведь он вполне может смотреть на содержимое структуры!
Кстати, ориентируясь на комментарий only integer compares :), можно заключить, что он сравнивает только какое-то целочисленное поле структуры, т.е. никак не значения указателей, а значения в структурах, на которые они указывают.
К моему превеликому удивлению дело оказалось действительно в компараторе, Harry в этом был прав. Обнаружил это, добавив в код компаратора вывод в консоль ключевой информации. Ни в документации Microsoft, ни на cppreference не нашёл никакого упоминания о том, что компаратор, используемый, казалось бы, только для упорядочивания элементов в контейнере, влияет на поведение компонентных функций.
Правда не понимаю, за что минусуют, вопрос-то касается максимально неочевидного нюанса, который запросто заставит потратить на отладку несколько часов как минимум