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

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

15.02.2022, 19:32. Показов 2505. Ответов 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,538
Записей в блоге: 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,361
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
13210 / 6843 / 1824
Регистрация: 18.10.2014
Сообщений: 17,306
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,538
Записей в блоге: 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
Ответ Создать тему
Новые блоги и статьи
сукцессия 15 неявная схема
anaschu 29.06.2026
Алиса Калибровка параметров симбиотической модели: технический обзор Содержание: Введение Постановка проблемы Технические аспекты реализации Процесс внедрения изменений
сукцессия 14. Обновленная схема модели
anaschu 28.06.2026
ГЛОБАЛЬНАЯ ОПИСАТЕЛЬНАЯ СПЕЦИФИКАЦИЯ ЭКОСИСТЕМНОЙ МОДЕЛИ «SOIL CHEMISTRY & MYCORRHIZA 2. 0» https:/ / ibb. co/ NnkGpfMd Представленная интегрированная схема описывает непрерывную нелинейную. . .
сукцессия 13. Питон модель трехзонного мицелия, пока что в основном арбускулярного
anaschu 28.06.2026
## Разработка агентной модели микоризной сукцессии: от выявления артефактов к созданию комплексной системы ### Аннотация Представлено исследование по разработке агентной модели микоризной. . .
сукцессия 12. краткий список проверок модели перед запуском.
anaschu 27.06.2026
Скрытые отказы в моделях систем динамики (SD-models) экологических систем: два случая из практики Контекст Разбирался прототип модели систем динамики (SD-модели) микоризной сукцессии: пять. . .
Сукцессия 11. Проверка орудий перед войной: разработка через тестирование
anaschu 27.06.2026
Как не дать модели соврать самой себе: проверки для симуляции микоризной сукцессии Введение Когда вы строите математическую модель живой системы — грибов, растений, почвы — главная опасность. . .
10 сукцессия. Питон код войны грибов и растений
anaschu 27.06.2026
import numpy as np class PlantAgent: def __init__(self, name, strategy, initial_biomass): self. name = name self. strategy = strategy # "greedy" (широколиственные) или. . .
сукцессия 9. Математика подлости: как растения предали грибных друзей
anaschu 27.06.2026
Статья 2. Глобальная фосфорная война: эволюционно-экономические механизмы распределения биомов Земли Введение: Экологический рынок как игра с нулевой суммой Традиционная экология долгое время. . .
сукцессия 8. Как я спорил с ИИ, которые - агенты растений и ненавистники грибов!
anaschu 27.06.2026
Статья 1. Хроники грибного восстания: как Сократов диалог разрушил академические догмы ИИ Введение: Синдром «цифрового учебника» Современные большие языковые модели (LLM) обладают колоссальным. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru