С Новым годом! Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 5.00/11: Рейтинг темы: голосов - 11, средняя оценка - 5.00
242 / 208 / 36
Регистрация: 19.02.2021
Сообщений: 1,431

Непонятка с std::multimap::begin

15.02.2022, 19:32. Показов 2387. Ответов 30
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте!

Прошу теоретической помощи, в инете не смог найти какой-то внятный ответ, или разъяснение по ситуации.

В некоем проекте в диспетчере событий используется std::multimap

C++
1
2
3
typedef std::multimap<int, CSXEventListenerT<TEnumEvent>*> CSXEventListenerTMultiMap;
...
CSXEventListenerTMultiMap m_aListeners;
В процессе инициализации программы туда добавляются элементы - "слушатели событий" с ключом, который определяет в каком порядке они будут обрабатывать события. Ключа всего три.

На определенном этапе нужно обработать события, запускается простой цикл и вызываются обработчики событий

C++
1
2
3
4
5
6
void DoReciveEvents(CSXEventArray& aEvents)
 {
    for (auto iter = m_aListeners.begin(); iter != m_aListeners.end(); ++iter)
    if ((*iter).second->IsListening() && !(*iter).second->IsOnceDisabled())
        (*iter).second->ReciveEvents(aEvents);
 }
Но почему-то m_aListeners.begin() позиционируется не на первом элементе.

Я пытался найти в инете и в пр. источниках подробное описание std::multimap::begin, но ничего такого, что помогло бы мне понять, почему begin() позиционируется не на первом элементе, я не нашел.
Просьба не сильно пинать ногами, если я что-то упустил.
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
15.02.2022, 19:32
Ответы с готовыми решениями:

Std::begin() ,std::end(),std::copy
...// int main() { std::vector&lt;double&gt; data;//Работает cout &lt;&lt; std::begin(data); double *data=new double; ...

std::begin, std::end для динамического массива c++
Работает нормально: int m = {1,2,3,4,5}; set &lt;int&gt; m_set{ begin(m),end(m) }; Не работает: int n;cin&gt;&gt;n; int *m =...

Std::multimap
есть ли какой ни будь способ БЫСТРОЙ проверки на наличие в мультипаме нужной пары? если есть не быстрая то это только цикл от begin до...

30
 Аватар для Kuzia domovenok
4268 / 3327 / 926
Регистрация: 25.03.2012
Сообщений: 12,531
Записей в блоге: 1
15.02.2022, 21:47
Студворк — интернет-сервис помощи студентам
Может это что-то многопоточное и к мапе обращаются без мьютекса?
0
 Аватар для lemegeton
4903 / 2696 / 921
Регистрация: 29.11.2010
Сообщений: 5,783
15.02.2022, 22:21
Constcat, ещё пару подлянок, которые можно посмотреть в коде:
1. Посмотрите,нНикто не меняет ключа готовых элементов?
C++
1
multimap.begin()->first -= 1; // bye-bye, birdy
Там, конечно, конст-корректность, но люди бывают очень изобретательны.

2. Покажите инициализацию мультимапы и то, как туда добавляются элементы.
0
242 / 208 / 36
Регистрация: 19.02.2021
Сообщений: 1,431
16.02.2022, 04:13  [ТС]
Цитата Сообщение от Алексей1153 Посмотреть сообщение
1) нужно попробовать ПОЛНЫЙ ребилд проекта - первым делом в случае таких непоняток
2) исключаем (или подтверждаем) глючность watcher :
Я завтра попробую, но тут такая ситуация - это, как уже понятно, менеджер событий, на который подписывается хорошая пачка контроллеров. А еще его (менеджера) может быть несколько копий. Подписанные контроллеры находятся в m_aListeners в течение всего сеанса работы программы. Подписка идет на этапе конструкторов контроллеров, а отписка - в деструкторах, в момент завершения программы.

Что меня особо удивляет - в менеджере подписано 12 контроллеров. В той процедуре, которую я отлаживаю, в цикле должны перебраться все контроллеры, и в зависимости от их состояния, им передается (или не передается) текущее событие.

Но begin() позиционируется на четвертый с конца, или (в другой ситуации) - на третий с конца.
И в цикле перебираются четыре или три последних контроллера из реально существующих 12.
Т.е., первые тупо игнорируются из-за того, что begin() почему-то указывает в конец.

У меня, к сожалению, опыта не так много, как хотелось бы, я сначала думал, что begin() перегружен и там по каким-то признакам определяется первый контроллер. Перегрузку не нашел. Потом искал перегрузку компаратора - тоже не нашел.

Идеи закончились. (((((

Добавлено через 13 минут
Цитата Сообщение от lemegeton Посмотреть сообщение
2. Покажите инициализацию мультимапы и то, как туда добавляются элементы.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
void AddListener(CSXEventListenerT<TEnumEvent> *pListener, int nOrderAdjustment = 0)
{
    typename CSXEventListenerTMultiMap::iterator iter;
    for (iter = m_aListeners.begin(); iter != m_aListeners.end(); ++iter)
        if ((*iter).second == pListener)
            break;
    if (iter != m_aListeners.end())
    {
        if ((*iter).first != nOrderAdjustment)
            RemoveListener(pListener);
        else
            return;
    }
    m_aListeners.insert(std::make_pair(nOrderAdjustment, pListener));
    pListener->AddEventManager(this);
}
void RemoveListener(CSXEventListenerT<TEnumEvent> *pListener)
{
    typename CSXEventListenerTMultiMap::iterator iter;
    for (iter = m_aListeners.begin(); iter != m_aListeners.end(); ++iter)
        if ((*iter).second == pListener)
            break;
 
    if (iter != m_aListeners.end())
    {
        (*iter).second->RemoveEventManager(this);
        m_aListeners.erase(iter);
    }
}
Кстати, не совсем понимаю использование typename при описании итератора. Вроде, не темплейт и не неоднозначная ситуация.


Цитата Сообщение от lemegeton Посмотреть сообщение
Посмотрите,никто не меняет ключа готовых элементов?
Не нашел. У нас подобное хакерство крайне не приветствуется. Могут случаться косяки, но не такого плана.
0
 Аватар для Новичок
1682 / 1098 / 489
Регистрация: 17.07.2012
Сообщений: 5,360
16.02.2022, 04:54
Цитата Сообщение от Constcat Посмотреть сообщение
Но почему-то m_aListeners.begin() позиционируется не на первом элементе.
А первый элемент какой должен быть и почему такой ? Покажите весь списоквсю мапу. Мапа элементы сортирует(хотя думаю вы это и так знаете). Есть ключ элемента уникальное значение, то не особо понятно зачем тут multimap. Покажите еще как вызывается AddListener.
0
242 / 208 / 36
Регистрация: 19.02.2021
Сообщений: 1,431
16.02.2022, 05:06  [ТС]
Цитата Сообщение от Новичок Посмотреть сообщение
А первый элемент какой должен быть и почему такой ? Покажите весь списоквсю мапу. Мапа элементы сортирует(хотя думаю вы это и так знаете). Есть ключ элемента уникальное значение, то не особо понятно зачем тут multimap.
Скрин мапы в рабочем состоянии в первом посте.
Ключи используются для определения порядка подписанных слушателей - некоторые должны получать событие раньше, чем другие.
В пределах одного ключа очередность обработки события слушателем неважна.
На скриншоте видно, что begin() позиционируется на элемент не с самым младшим ключом.

Цитата Сообщение от Новичок Посмотреть сообщение
Покажите еще как вызывается AddListener.
Это как? Он вызывается много раз при создании каждого контроллера. Более того, его в самой программе несколько копий.
В той копии, что я отлаживаю, 12 контроллеров. В другой, до которой я еще не добрался - порядка 10.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12930 / 6798 / 1819
Регистрация: 18.10.2014
Сообщений: 17,205
16.02.2022, 05:23
Цитата Сообщение от Новичок Посмотреть сообщение
Покажите весь списоквсю мапу.
На скрине в вопросе она видна.

Цитата Сообщение от Новичок Посмотреть сообщение
Мапа элементы сортирует(хотя думаю вы это и так знаете).
Ключом является int, а компаратором - std::less. На скрине это видно. И там же видно, что она прекрасно отсортирована по ключу.

Цитата Сообщение от Новичок Посмотреть сообщение
Есть ключ элемента уникальное значение, то не особо понятно зачем тут multimap.
По коду понятно, что это такое. Ключ - это условный "приоритет" в компании "слушателей". Он не является уникальным. Равноприоритетные слушатели - штатная ситуация.
1
 Аватар для lemegeton
4903 / 2696 / 921
Регистрация: 29.11.2010
Сообщений: 5,783
16.02.2022, 12:31
Цитата Сообщение от Constcat Посмотреть сообщение
void AddListener(CSXEventListenerT<TEnumEvent > *pListener, int nOrderAdjustment = 0)
{
    typename CSXEventListenerTMultiMap::iterator iter;
    for (iter = m_aListeners.begin(); iter != m_aListeners.end(); ++iter)
        if ((*iter).second == pListener)
            break;
    if (iter != m_aListeners.end())
    {
        if ((*iter).first != nOrderAdjustment)
            RemoveListener(pListener);
        else
            return;
    }
    m_aListeners.insert(std::make_pair(nOrde rAdjustment, pListener));
    pListener->AddEventManager(this);
}
void RemoveListener(CSXEventListenerT<TEnumEv ent> *pListener)
{
    typename CSXEventListenerTMultiMap::iterator iter;
    for (iter = m_aListeners.begin(); iter != m_aListeners.end(); ++iter)
        if ((*iter).second == pListener)
            break;
if (iter != m_aListeners.end())
    {
        (*iter).second->RemoveEventManager(this);
        m_aListeners.erase(iter);
    }
}
Чёт мне тут не нравится. Как-то тут слишком сложно.

Покажите, пожалуйста, всё-таки, как инициализируется m_aListeners. Конструктор может быть?

Добавлено через 6 минут
Ещё рекомендую найти все упоминания m_aListeners в коде и вчитаться.
1
242 / 208 / 36
Регистрация: 19.02.2021
Сообщений: 1,431
16.02.2022, 13:29  [ТС]
Цитата Сообщение от lemegeton Посмотреть сообщение
Покажите, пожалуйста, всё-таки, как инициализируется m_aListeners. Конструктор может быть?
m_aListeners в стеке. В конструкторе он никак дополнительно не инициализируется.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
CSXEventManagerT(bool bUseEventContainer=false)
{
    m_bDisableAddEventInFlush = true;
    m_bDoFlushEvents = false;
    m_bLoopFlush = false;
    if (bUseEventContainer)
        m_pEventContainer = new CSXEventContainerType();
    else
        m_pEventContainer = NULL;
    // Создание первого активного массива для событий
    CSXEventArray aArray;
    m_aEvents.push_back(aArray);
}
Беру небольшой тайм-аут.
После очистки и пересборки всего проекта полезли другие глюки. Перестал срабатывать брейкпоинт в тех ситуациях, когда я его ожидал. Т.е., управление туда перестало передаваться.
Отпишусь, когда разберусь.
0
 Аватар для Kuzia domovenok
4268 / 3327 / 926
Регистрация: 25.03.2012
Сообщений: 12,531
Записей в блоге: 1
16.02.2022, 13:45
Как можно было всё так переусложнить, что за...
Задача, просто обновить значение в мапе по ключу,
нет.... пройдёмся одним циклом, пройдёмся вторым циклом, сначала удалим, потом добавим, а когда будем удалять, то может быть и передумаем удалять...
0
242 / 208 / 36
Регистрация: 19.02.2021
Сообщений: 1,431
16.02.2022, 15:36  [ТС]
Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
Как можно было всё так переусложнить, что за...
Задача, просто обновить значение в мапе по ключу,
нет.... пройдёмся одним циклом, пройдёмся вторым циклом, сначала удалим, потом добавим, а когда будем удалять, то может быть и передумаем удалять...
Проекту более 10 лет. Он прошел через руки не одного десятка программеров.
Так что это все уже легаси. )))
0
242 / 208 / 36
Регистрация: 19.02.2021
Сообщений: 1,431
17.02.2022, 01:00  [ТС]
Коллеги!

Ситуация с multimap разъяснилась.

Большое спасибо всем принявшим участие и выразившим основную мысль, что такое поведение совершенно неправильное.
Всему виною моя невнимательность.

Дело в том, что для того, чтобы добраться до проблемного места в программе, нужно было "прокликать" брейкпоинт на этом цикле добрую сотню раз.
Поэтому я определил приблизительный участок кода перед возникновением проблемной ситуации и там установил брейкпоинт.
А вот потом уже ставил брейкпоинт на начало обсуждаемого цикла и смотрел, что там происходит.

Так вот. Я совершенно не обратил внимание на то, что к этому моменту весь код, который был в стеке, уже выполнялся внутри этого цикла очередной итерацией.
А поскольку брейкпоинт я ставил непосредственно на строку с for, то этого не заметил.

Еще раз всем спасибо!
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
17.02.2022, 01:00
Помогаю со студенческими работами здесь

Не дает добавить в std::multimap
почему не дает добавить? подчеркивает слово pair и пишет: я сразу же загуглил но в описании к моему случаю ниодин пример не подходит. ...

Вывести на консоль все элементы std::multimap
Приветствую, Подскажите, возможно ли у std::multimap - вывести все элементы на консоль ? std::multimap&lt;int,...

Реализация std::list<>::begin()
Вопрос строго для знатоков реализации STL. Каким образом реализована &quot;перегрузка&quot; у списка метода begin() только по возвращаемому...

Multimap. Ошибка operator+ not implemented in type multimap
Я начинающий в си, есть задача подсчета частоты встречаемости символов, делал через ассоциативный массив map&lt;char, int&gt;, программа...

Не воспринимает ни std::cout, ни std::cin. Вобщем ничего из std. Также не понимает iostream
Здравствуйте! Я хотел начать изучать язык C++. Набрал литературы. Установил Microsoft Visual C++ 2005 Express Edition. Образ диска...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
31
Ответ Создать тему
Новые блоги и статьи
Модель микоризы: классовый агентный подход
anaschu 02.01.2026
Раньше это было два гриба и бактерия. Теперь три гриба, растение. И на уровне агентов добавится между грибами или бактериями взаимодействий. До того я пробовал подход через многомерные массивы,. . .
Учёным и волонтёрам проекта «Einstein@home» удалось обнаружить четыре гамма-лучевых пульсара в джете Млечного Пути
Programma_Boinc 01.01.2026
Учёным и волонтёрам проекта «Einstein@home» удалось обнаружить четыре гамма-лучевых пульсара в джете Млечного Пути Сочетание глобально распределённой вычислительной мощности и инновационных. . .
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru