Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.85/13: Рейтинг темы: голосов - 13, средняя оценка - 4.85
75 / 59 / 31
Регистрация: 20.03.2017
Сообщений: 351

Структура как ключ map, возможно ли как-то реализовать operator []

19.04.2018, 15:30. Показов 2912. Ответов 6
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Возможно бред, но всё же.
Реализовать сам ключ не сложно, вот код:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class cKey 
{
public:
    cKey(){}
    cKey(TIMER_ID timer, PhraseID_t id):timer(timer), PhraseID(id){}
    ~cKey(){}
 
    TIMER_ID timer;
    PhraseID_t PhraseID;
};
 
typedef cKey mapkey_t;
 
inline const bool operator< (const cKey &left, const cKey &right)
{
    if(/*(*/left.PhraseID < right.PhraseID/*) && (left.PhraseID < right.PhraseID)*/)
        return true;
    return false;
 
}
Проблема вот в чем:
в некоторых функциях будет в виде параметра использоваться не полностью ключ, а только часть его,к примеру:
C++
1
2
3
4
5
6
7
8
function1(..., const PhraseID_t &id, ...)
{
    ******
}
function2(..., TIMER_ID id, ...)
{
    ******
}
Возможно ли как-то реализовать
C++
1
operator []
для такой map-ы, чтобы можно было обращаться не по полному ключу, а по одному из полей класса?
Или у кого есть другие варианты как это дело провернуть.
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
19.04.2018, 15:30
Ответы с готовыми решениями:

Как взять значение и ключ из Map?
мне нужно сравнить все значения в мэпе с определенным значением. мне нужно взять каждый ключ и каждое значение из него. как это сделать?...

Контейнер Map. Использование класса как ключ
class A{ int X;}; class B{ public: int y;}; int main() { A objA; B objB; map&lt;A,B&gt; m; m.y=1; //kak? ...

Как поменять ключ в map на другой, сохранив значение?
Задача: нужно выборочно поменять любой ключ в словаре map, сохранив при этом его значение. Например, есть пара ключ значение &quot;111...

6
Форумчанин
Эксперт CЭксперт С++
 Аватар для MrGluck
8216 / 5047 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
19.04.2018, 15:40
Не понял до конца что требуется, для одной типы мапы ключ => значение определить разные компараторы?
Тогда пример ниже.
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
30
31
32
33
34
35
36
37
38
39
40
41
#include <iostream>
#include <map>
 
struct TIMER_ID
{
    int x;
};
 
bool operator<(const TIMER_ID &lhs, const TIMER_ID &rhs)
{
    return lhs.x < rhs.x;
}
 
struct MyS
{
    TIMER_ID id;
    int anotherData;
};
 
struct MySCmpTimer
{
    bool operator()(const MyS &lhs, const MyS &rhs) const
    {
        return lhs.id < rhs.id;
    }
};
 
struct MySCmpAnotherData
{
    bool operator()(const MyS &lhs, const MyS &rhs) const
    {
        return lhs.anotherData < rhs.anotherData;
    }
};
 
int main()
{
    std::map<MyS, int, MySCmpTimer> m1; // сравнение по TIMER_ID
    std::map<MyS, int, MySCmpAnotherData> m2; // сравнение по anotherData
    std::map<MyS, int> m3(MySCmpTimer), m4(MySCmpAnotherData);
}
0
зомбяк
 Аватар для TRam_
1585 / 1219 / 345
Регистрация: 14.05.2017
Сообщений: 3,940
19.04.2018, 15:42
Лучший ответ Сообщение было отмечено qwe123qwea как решение

Решение

Нельзя. Нужно две map, каждая под свой ключ, а объекты оборачивать в умные указатели и синхронно добавлять/удалять в обоих мапах.
1
75 / 59 / 31
Регистрация: 20.03.2017
Сообщений: 351
19.04.2018, 15:46  [ТС]
MrGluck, map-у я хочу одну сделать с ключом в виде класса
C++
1
class cKey
, но в проге есть callback-и в которых возвращается только одно из полей класса
C++
1
class cKey
, и хотелось бы обращаться как к массиву через
C++
1
[]
Добавлено через 1 минуту
TRam_, спасибо. Печально однако.
0
75 / 59 / 31
Регистрация: 20.03.2017
Сообщений: 351
21.04.2018, 11:57  [ТС]
TRam_, как-то так должно выглядель:
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
#include <iostream>
#include <cstring>
#include <map>
#include <typeinfo>
#include <memory>
 
#define NETWORK_PROTOCOL_MAX_FEEDERS_COUNT  32
#define NETWORK_PROTOCOL_MAX_PHRASE_COUNT   64
#define NOT_FOUND                           -1
#define _FAIL                                0x01
#define _OK                                  0x00
 
#pragma pack(push, 1)
struct sBuildStatePhrase
{
    SURA_RESULT state;
    char count_samples;      // максимум 64
    PhraseID_t P_ID;
    TIMER_ID T_ID;
    sRequestBegin msg;
    IPv4Address senderAddr;
    IPv4Port senderPort;
    sBuildStatePhrase()
        : state(_FAIL)
        , count_samples(0x00)
        , P_ID(NOT_FOUND)
        , T_ID(NOT_FOUND)
        , senderAddr(NOT_FOUND)
        , senderPort(NOT_FOUND)
    {
        memset(&msg, 0, sizeof(msg));
    }
    sBuildStatePhrase(SURA_RESULT st, char count, TIMER_ID TimID, PhraseID_t PhrID, sRequestBegin& _msg, IPv4Address addr, IPv4Port port)
        : state(st)
        , count_samples(count)
        , P_ID(PhrID)
        , T_ID(TimID)
        , msg(_msg)
        , senderAddr(addr)
        , senderPort(port)
    {
    }
};
#pragma pack(pop)
 
class cKey // ключ для sBuildStatePhrase
{
public:
    cKey(){}
    cKey(TIMER_ID time, PhraseID_t id):T_ID(time), P_ID(id){}
    ~cKey(){}
    TIMER_ID T_ID;
    PhraseID_t P_ID;
};
typedef cKey key_t;
 
typedef std::map<PhraseID_t, key_t> mapKey;
typedef std::pair<PhraseID_t, key_t> Int_Pair_Key;
typedef std::map<PhraseID_t, key_t>::iterator itKey;
 
typedef std::map<TIMER_ID, shared_ptr<sBuildStatePhrase>> mapStatePhraaeTimer;
typedef std::pair<TIMER_ID, shared_ptr<sBuildStatePhrase>> Int_Pair_Timer;
typedef std::map<TIMER_ID, shared_ptr<sBuildStatePhrase>>::iterator itStatePhraaeTimer;
 
typedef std::map<PhraseID_t, shared_ptr<sBuildStatePhrase>> mapStatePhraaeID;
typedef std::pair<PhraseID_t, shared_ptr<sBuildStatePhrase>> Int_Pair_ID;
typedef std::map<PhraseID_t, shared_ptr<sBuildStatePhrase>>::iterator itStatePhraaeID;
 
 
class cTwoMaps
{
public:
    cTwoMaps():count(0){}
    ~cTwoMaps(){}
    enum result
    {
        E_TIMERID = -2, // нет записи с таким ID таймера
        E_PHRASEID,     // нет записи с таким ID фразы
        OK,
        E_ADDTIMER,     // не добавлена запись, т.к. запись с таким ID таймера уже существует
        E_ADDPHRASE,    // не добавлена запись, т.к. запись с таким ID фразы уже существует
        INVALID_KEY_T,  // неверный ключ(id фразы есть, id таймера нет)
        INVALID_KEY_P,  // неверный ключ(id фразы нет, id таймера есть)
        INVALID_KEY,    // неверный ключ
    };
 
    template<typename T>
    shared_ptr<sBuildStatePhrase> operator[](T id)
    {
        if(typeid(T) == typeid(TIMER_ID))
            return timer[id];
        else if(typeid(T) == typeid(PhraseID_t))
            return timer[key[id].id_timer];
    }
    result insert(key_t id, shared_ptr<sBuildStatePhrase>& data);
    result insert(TIMER_ID id, PhraseID_t id_p, shared_ptr<sBuildStatePhrase>& data);
    result erase(key_t &key_id);
    result erase(TIMER_ID id);
    result erase(PhraseID_t id);
    size_t size(){return count;}
 
 
private:
    mapStatePhraaeTimer timer;
    mapKey              key;
    size_t              count;
};
 
cTwoMaps::result cTwoMaps::insert(key_t id, shared_ptr<sBuildStatePhrase>& data)
{
//    mutex.lock()
    if(timer.find(id.T_ID) == timer.end())
    {
        if(key.find(id.P_ID) == key.end())
        {
            auto res_t = timer.insert(Int_Pair_Timer(id.T_ID, data));
            if(res_t.second)
            {
                auto res_p = key.insert(Int_Pair_Key(id.P_ID, id));
                if(res_p.second)
                {
                    count++;
//                    mutex.unlock()
                    return OK;
                }
//                mutex.unlock()
                return E_ADDPHRASE;
            }
//            mutex.unlock()
            return E_ADDTIMER;
        }
//        mutex.unlock()
        return E_PHRASEID;
    }
//    mutex.unlock()
    return E_TIMERID;
}
cTwoMaps::result cTwoMaps::insert(TIMER_ID id_t, PhraseID_t id_p, shared_ptr<sBuildStatePhrase>& data)
{
//    mutex.lock()
    if((timer.find(id_t) == timer.end())/* || (t_key.empty())*/)
    {
        if((key.find(id_p) == key.end())/* || (p_key.empty())*/)
        {
            auto res_t = timer.insert(Int_Pair_Timer(id_t, data));
            if(res_t.second)
            {
                key_t id(id_t, id_p) ;
                auto res_p = key.insert(Int_Pair_Key(id_p, id));
                if(res_p.second)
                {
                    count++;
//                    mutex.unlock()
                    return OK;
                }
//                mutex.unlock()
                return E_ADDPHRASE;
            }
//            mutex.unlock()
            return E_ADDTIMER;
        }
//        mutex.unlock()
        return E_PHRASEID;
    }
//    mutex.unlock()
    return E_TIMERID;
}
 
cTwoMaps::result cTwoMaps::erase(TIMER_ID id)
{
    // mutex.lock()
    auto it_t = timer.find(id);
    if(it_t != timer.end())
    {
        auto it_p = key.find(it_t->second->P_ID);
        if((it_t->second->T_ID == id) && (it_t->second->P_ID == it_p->second.P_ID) && (it_t->second->T_ID == it_p->second.T_ID))
        {
            key.erase(it_t->second->P_ID);
            timer.erase(id);
            count--;
//            mutex.unlock()
            return OK;
        }
//        mutex.unlock()
        return INVALID_KEY_P;
    }
//    mutex.unlock()
    return E_TIMERID;
}
cTwoMaps::result cTwoMaps::erase(PhraseID_t id)
{
//    mutex.lock()
    auto it_p = key.find(id);
    if(it_p != key.end())
    {
        auto it_t = timer.find(it_p->second.T_ID);
        if((it_p->second.P_ID == id) && (it_p->second.P_ID == it_t->second->P_ID) && (it_p->second.T_ID == it_t->second->T_ID))
        {
            timer.erase(it_p->second.T_ID);
            key.erase(id);
            count--;
//            mutex.unlock()
            return OK;
        }
//        mutex.unlock()
        return INVALID_KEY_T;
    }
//    mutex.unlock()
    return E_PHRASEID;
}
cTwoMaps::result cTwoMaps::erase(key_t &key_id)
{
//    mutex.lock()
    auto it_t = timer.find(key_id.T_ID);
    if((it_t != timer.end()))
    {
        if(it_t->second->P_ID == key_id.P_ID)
        {
            auto it_p = key.find(key_id.P_ID);
            if(it_p != key.end())
            {
                if(it_p->second.T_ID == key_id.T_ID)
                {
                    key.erase(key_id.P_ID);
                    timer.erase(key_id.T_ID);
                    count--;
//                    mutex.unlock()
                    return OK;
                }
//                mutex.unlock()
                return INVALID_KEY;
            }
//            mutex.unlock()
            return E_PHRASEID;
        }
//        mutex.unlock()
        return INVALID_KEY;
    }
//    mutex.unlock()
    return E_TIMERID;
}
У меня вопрос, такой: стоит ли
C++
1
operator[]
так перегружать или есть более правильное решение?
0
зомбяк
 Аватар для TRam_
1585 / 1219 / 345
Регистрация: 14.05.2017
Сообщений: 3,940
21.04.2018, 12:58
Цитата Сообщение от qwe123qwea Посмотреть сообщение
стоит ли так перегружать
Динамический полиморфизм тут, думаю, только вреден. Просто 2 перегрузки этого оператора с разными типами аргументов:

C++
1
2
shared_ptr<sBuildStatePhrase> operator[](TIMER_ID id);
shared_ptr<sBuildStatePhrase> operator[](PhraseID_t id);
1
75 / 59 / 31
Регистрация: 20.03.2017
Сообщений: 351
21.04.2018, 13:13  [ТС]
TRam_, Спасибо.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
21.04.2018, 13:13
Помогаю со студенческими работами здесь

std::map find. Получить ключ(элемент) и как записать все данные при объявлений?
Вопрос первый: как получить ключ контейнера map по данным? например: // id, name std::map&lt;int, string&gt; BookMap; BookMap...

Как называется эта структура и как ее реализовать в Дельфи?
В винде есть реестр реально ли это реализовать в делфи с одной стороны это массив стринг но с другой стороны это дерево с...

Возможно ли в Делфи проигрывание семи нот, как в Турбо Паскале, и как это реализовать?
Даны ноты и какие то коды рядом с ними все это я нашел в Турбо Паскале, тока ввожу в поисковик Делфи и ноты и врезультате получаю...

Структура современной связи как структура системы власти - как структура государственного управления
Структура современной связи всё больше становится структурой государственного управления, в особенности финансового государственного...

Как реализовать код без применения ассоциативного массива (map)?
Имеется такой код. Как можно его изменить, не использую массив map? #include &lt;iostream&gt; #include &lt;map&gt; #include &lt;string&gt; ...


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

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Новые блоги и статьи
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip Сканируйте QR-код на мобильном и вы увидите, что появится джойстик для управления главным героем. . . .
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка библиотек: SDL3, Box2D, FreeType, SDL3_ttf, SDL3_mixer и SDL3_image из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru