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

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

15.02.2022, 19:32. Показов 2609. Ответов 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 / 3328 / 926
Регистрация: 25.03.2012
Сообщений: 12,545
Записей в блоге: 1
15.02.2022, 21:47
Студворк — интернет-сервис помощи студентам
Может это что-то многопоточное и к мапе обращаются без мьютекса?
0
 Аватар для lemegeton
4904 / 2697 / 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
13235 / 6867 / 1827
Регистрация: 18.10.2014
Сообщений: 17,405
16.02.2022, 05:23
Цитата Сообщение от Новичок Посмотреть сообщение
Покажите весь списоквсю мапу.
На скрине в вопросе она видна.

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

Цитата Сообщение от Новичок Посмотреть сообщение
Есть ключ элемента уникальное значение, то не особо понятно зачем тут multimap.
По коду понятно, что это такое. Ключ - это условный "приоритет" в компании "слушателей". Он не является уникальным. Равноприоритетные слушатели - штатная ситуация.
1
 Аватар для lemegeton
4904 / 2697 / 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 / 3328 / 926
Регистрация: 25.03.2012
Сообщений: 12,545
Записей в блоге: 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
Ответ Создать тему
Новые блоги и статьи
Особенности gif сгенерированных в Си
russiannick 21.10.2026
Рассмотрим генерацию gif файлов, которые в Си имеют свои особенности. Gif представляет собой графический формат популярный в интернете. Посмотрим на палитру. Gif файл сгенерированный в си отличается. . .
FPS контроллер с анимированными Y-Bot и 3D-звуком miniaudio (Box3D, Recast, BehaviorTree.CPP, ozz-animation, ImGui, OpenGL и SDL3)
8Observer8 18.10.2026
Содержание блога | English Version Полное мультиплатформенное руководство по стартовому проекту с FPS-контроллером игрока, анимированными роботами Y-Bot с 4-слойным блендингом, 3D-физикой Box3D,. . .
Локальный http сервер
Argus19 17.10.2026
Локальный http сервер На работе, на двух локальных компьютерах круглосуточно работают программы опроса приборов с записью в книги Excel,которые раз в сутки записываются на сервер компании. Т. к. . . .
Копировать Windows на новый диск на UEFI
damix 17.10.2026
https:/ / uriesk. wordpress. com/ 2016/ 11/ 01/ move-window-10-to-ssd-on-a-uefi-dualboot-system-with-basic-linux-tools/ TL DR Вставляем диск, а старый подключаем через переходник, грузимся с лайва. . .
ИИ не может найти нужный язык в списке
Supersumestria 05.10.2026
Я ему даю вот такое изображение и прошу найти и подчеркнуть немецкий язык. Возвращает он вот это: https:/ / i. **********/ vqBWLe2. png Нужную строчку в 3й колонке просто выдумал. . Это. . .
Новая последняя моя музыка в SUNO
zorxor 05.10.2026
Здравствуйте, дорогие мои друзья! С большой радостью я хотел бы представить вам свою новую последнею музыку, которую сгенерировала мне по моей просьбе нейросеть SUNO. С уважением, zorxor. Это. . .
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js. В помощники взял Яндекс-Алису. Было создано три зала на разные интересы. исторические и ретро сериал Хичкок. . .
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru