Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.78/9: Рейтинг темы: голосов - 9, средняя оценка - 4.78
7 / 7 / 0
Регистрация: 14.03.2013
Сообщений: 221
1

Как получить копию pair из map контейнера?

26.08.2019, 12:59. Показов 1720. Ответов 8
Метки нет (Все метки)

Всем привет. Имеется внутри класса контейнер map, у класса есть метод который возвращает при каждом вызове, следующий элемент контейнера (либо пустую пару если достигнут конца):

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
....
private:
map<string, string> args;
....
public:
const pair<string, string>& getOptionArgument()
    {
        if (it == args.end())
        {
            static const pair<string, string> empty_pair("", "");
            return empty_pair;
        }
        static const pair<string, string> pair_res(it->first, it->second);
        it++;
        return pair_res;
    }
...
Прошу взгляните на этот код, его можно как нибудь оптимизировать? Мне не нравится сам факт копирования пары... возможно такой код избыточен? Что думаете?
0

Помощь в написании контрольных, курсовых и дипломных работ здесь.

Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
26.08.2019, 12:59
Ответы с готовыми решениями:

Map : как по номеру элемента получить сам элемент контейнера?
Додумался только до такого: int n = 2; std::map&lt; String, String &gt; MASS; std::map&lt;String,...

Из каждого элемента контейнера map вычесть среднее арифметическое контейнера
Контейнер map, тип элементов Int 3.Из каждого элемента вычесть среднее арифметическое контейнера

Map<string,vector<pair<string,vector<int> > > > Поиск во всем map
Как пройти циклом по всему map такого вида? map&lt; string, vector&lt; pair&lt; string, vector&lt;int&gt; &gt; &gt; &gt;...

Как в vector<pair <класс, int> > добавлять свой объект в качестве первого элемента pair?
#include&lt;iostream&gt; #include &quot;Employee.h&quot; #include&lt;string&gt; #include&lt;algorithm&gt; #include&lt;vector&gt;...

8
6737 / 4537 / 1838
Регистрация: 07.05.2019
Сообщений: 13,725
Записей в блоге: 1
26.08.2019, 13:04 2
Цитата Сообщение от oleggy Посмотреть сообщение
Прошу взгляните на этот код, его можно как нибудь оптимизировать? Мне не нравится сам факт копирования пары... возможно такой код избыточен? Что думаете?
C++
1
2
3
4
5
6
7
8
9
const pair<string, string>& getOptionArgument()
    {
        if (it == args.end())
        {
            static const pair<string, string> empty_pair("", "");
            return empty_pair;
        }
        return *(it++);
    }
1
Don't worry, be happy
17142 / 10019 / 1933
Регистрация: 27.09.2012
Сообщений: 24,944
Записей в блоге: 1
26.08.2019, 13:13 3
Лучший ответ Сообщение было отмечено oleggy как решение

Решение

oleg-m1973, этот код в принципе не верен.
Контейнер map<string, string> содержит пары pair<const string, string>, а не pair<string, string>, так что ссылку Вы возвращаете на временный объект, а не ссылку на пару в map'е. Временный объект этот будет убит при выходе из функции и ссылка "повиснет".
5
6737 / 4537 / 1838
Регистрация: 07.05.2019
Сообщений: 13,725
Записей в блоге: 1
26.08.2019, 13:16 4
Цитата Сообщение от Croessmah Посмотреть сообщение
oleg-m1973, этот код в принципе не верен.
Ну да, ошибка есть
C++
1
2
3
4
5
6
7
8
9
const auto& getOptionArgument()
    {
        if (it == args.end())
        {
            static const  map<string, string>::value_type empty_pair("", "");
            return empty_pair;
        }
        return *(it++);
    }
1
7 / 7 / 0
Регистрация: 14.03.2013
Сообщений: 221
27.08.2019, 08:37  [ТС] 5
Понял, но тогда выходит и в 5 строке нужно тоже скорректировать, добавив const:

C++
1
2
3
4
5
6
7
8
9
const pair<const string, string>& getOptionArgument()
    {
        if (it == args.end())
        {
            static const pair<const string, string> empty_pair("", "");
            return empty_pair;
        }
        return *(it++);
    }
Потому что создается временный объект тоже. Компилятор предупреждение кидает: warning: returning reference to local temporary object
вопрос:
мне не понятно, даже если у меня данная переменная empty_pair статическая, все равно она будет временной после завершения метода? все из за того что ее в ней тип ключа не const? Так?

вопрос 2:
выше предложено в заголовке метода использовать auto:
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
const auto& getOptionArgument()
{...}
вопрос, это нормально с точки зрения читаемости кода? никто ругаться не будет? ведь зачастую сложно с первого взгляда понять какой тип возвращает метод..

Добавлено через 3 часа 28 минут
вопрос 3:
метод getOptionArgument() работает, все нормально.. но как в данном коде изменить строку 3 что бы компилятор не ругался - no viable overloaded '=':
C++
1
2
3
4
    for (const auto& arg = cmd.getOptionArgument(true);
                                arg != empty_pair; 
                                arg = cmd.getOptionAndArgument())
    {...}
компилятор ругается на то что отсутствует перегруженный оператор '=' для ссылки?
0
6737 / 4537 / 1838
Регистрация: 07.05.2019
Сообщений: 13,725
Записей в блоге: 1
27.08.2019, 08:55 6
Цитата Сообщение от oleggy Посмотреть сообщение
вопрос, это нормально с точки зрения читаемости кода? никто ругаться не будет? ведь зачастую сложно с первого взгляда понять какой тип возвращает метод..
Да, вполне нормально.
А вот использовать здесь
Код
std::pair<.........>
- ненормально. Нужно использовать map<string, string>::value_type

Цитата Сообщение от oleggy Посмотреть сообщение
вопрос 3:
метод getOptionArgument() работает, все нормально.. но как в данном коде изменить строку 3 что бы компилятор не ругался - no viable overloaded '=':
Потому что не надо здесь использовать cmd.getOptionArgument(true), сделай нормальный цикл по итераторам.
0
7 / 7 / 0
Регистрация: 14.03.2013
Сообщений: 221
27.08.2019, 09:11  [ТС] 7
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Потому что не надо здесь использовать cmd.getOptionArgument(true), сделай нормальный цикл по итераторам.
я просто хотел бы скрыть доступ к самому map, поэтому и создал такой метод который возвращает копию элемента (пару) из map.
Придумал вот такой цикл.
C++
1
2
3
4
5
6
    while (true)
    {
        const auto& arg = cmd.getOptionAndArgument();
        if (arg == empty_pair) break;
        ...
    }
Это решение лучше?
0
6737 / 4537 / 1838
Регистрация: 07.05.2019
Сообщений: 13,725
Записей в блоге: 1
27.08.2019, 09:18 8
Цитата Сообщение от oleggy Посмотреть сообщение
Это решение лучше?
Не слишком, но хотя бы будет работать

Цитата Сообщение от oleggy Посмотреть сообщение
я просто хотел бы скрыть доступ к самому map, поэтому и создал такой метод который возвращает копию элемента (пару) из map.
Ты ничего не здесь не скрываешь. Сделай лучше методы begin() - end() - find(), котрые будут возвращать std::map<....>::iterator
А ещё лучше не заморачивайся и сделай оператор const std::map<.....> *operator ->() const noexcept {return &args;}
0
Комп_Оратор)
Эксперт по математике/физике
8719 / 4425 / 598
Регистрация: 04.12.2011
Сообщений: 13,256
Записей в блоге: 16
28.08.2019, 22:21 9
Цитата Сообщение от oleggy Посмотреть сообщение
it == args.end()
oleggy, it покажите. Вы объявили итератор полем класса?

Добавлено через 18 минут
Пока вы молчите я покажу как бы я решил в пределах возможностей от самой карты:
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
#include <iostream>
#include <map>
using namespace std;
 
 
map<string, string> options{{"mama","this is mama"}, {"papa","mam's man"},{"me","wher am I"}};
map<string, string>::const_iterator end_map=options.end();
map<string, string>::const_iterator
getPairByStrinKey(string key)
{
   return  options.find(key);
}
 
 
int main()
{
string
tofind="papa";
map<string, string>::const_iterator
it=getPairByStrinKey(tofind);
if(it!=end_map)cout<<it->second << endl;
else cout << tofind << " not found" << endl;
 
tofind="popa";
it=getPairByStrinKey(tofind);
if(it!=end_map)cout<<it->second << endl;
else cout << tofind << " not found" << endl;
 
    return 0;
}
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
28.08.2019, 22:21

Помощь в написании контрольных, курсовых и дипломных работ здесь.

Вывод контейнера map
Подскажите пожалуйста как вывести на экран значение карты. Программа такая: надо создать карту, где...

Использование контейнера map
Доброе утро) Никак не пойму как пользоваться контейнером map и зачем он, вообще, нужен?! Скажем...

Реализация контейнера по типу map
Необходимо создать пользовательский класс по типу map, для реализации &quot;словаря&quot;. Можете помочь с...

Копирование содержимого контейнера map
Итак, есть контейнер map&lt;string,fsElem *&gt;, где fsElem - базовый класс, также есть наследуемый от...


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

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.