Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 30, средняя оценка - 4.90
IcyWind
8 / 8 / 2
Регистрация: 19.09.2011
Сообщений: 269
#1

Лямбда выражения - C++

10.11.2011, 14:33. Просмотров 3978. Ответов 31
Метки нет (Все метки)

Здрасьте)
вопрос по новому стандарту, в который ввели лямбда-выражения.
создаю класс, у которого есть поле data, типа map.
C++
1
map <string, list<string> > data;
заполняю его. и теперь мне нужно отсортировать списки, которые в нём находятся.
первый логичный вариант -
C++
1
2
for(map <string, list<string> > :: iterator p = data.begin(); p != data.end(); ++p)
                    p->second.sort();
(кстати, в этом случае - всё прекрасно работает)
но задание у меня такого, что нельзя использовать циклы, тогда пробую так:
C++
1
2
3
4
for_each(data.begin(), data.end(), [](pair<string, list<string> > p)
                 {
                     p.second.sort();
                 });
но при вызове
C++
1
2
3
4
5
6
7
8
9
10
11
map<string, list<string> > :: iterator p = data.begin();
for_each(&mas[0], &mas[size],[&p, &result](int x)
        {
            if (x == 1)
            {
                list<string> help;
                set_intersection(result.begin(), result.end(), p->second.begin(), p->second.end(), back_inserter(help));                
                result.assign(help.begin(), help.end());
                ++p;
            }
}
обнаруживается, что списки в мэпе не отсортированы!
возвращиюсь к сорту (с помощью лямбды) вывожу значения всего мепа (по спискам) и дейстительно! лямбда-выражение его не отсортировало.
Появилась идея, что нужно включить data в список захвата, но строчка
C++
1
2
3
4
for_each(data.begin(), data.end(), [&data](pair<string, list<string> > p)
                 {
                     p.second.sort();
                 });
не компилируется, ибо data - член класса, который "не является переменной".

Если нужен полный код - вот он.
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
// Var 9.cpp: определяет точку входа для консольного приложения.
//Имеется список 40 студентов, изучающих математику, физику, биологию и химию, заданный в файле в виде строк 
//Фамилия    предмет
 
//Каждый предмет изучает около 20 студентов. Разработать структуры данных, позволяющих эффективно отвечать на запросы вида 
//«Выдать всех студентов, изучающих биологию и химию, но не изучающих физику».
 
#include "stdafx.h"
#include <algorithm>
#include <iostream>
#include <string>
#include <fstream>
#include <list>
#include <map>
#include <iterator>
using namespace std;
 
/*
биологию   mas[0]
математику mas[1]
физику     mas[2]
химию      mas[3]
*/
 
class stud_file
{
map <string, list<string> > data;
list<string> all_stud;
 
public:
    
    stud_file (string s) 
    {
        ifstream FS; //Fs(s) ?
        FS.open(s);
                 string Fam, pred;
                 while(!FS.eof()) //а как читать?
                 {
                    FS >> Fam;
                    FS >> pred;
                    data[pred].push_back(Fam);
 
                    list<string> :: iterator pb = all_stud.begin();
                    list<string> :: iterator pe = all_stud.end();
                    if (find(pb, pe, Fam) == pe)
                    {
                        all_stud.push_back(Fam);
                    }
 
                 }
                 FS.close();
 
                 all_stud.sort(); //надо сортировать
                 
                 for_each(data.begin(), data.end(), [&data](pair<string, list<string> > p)
                 {
                     p.second.sort();
                 });
 
 
 
                 for(auto it = data.begin(); it!= data.end(); ++it)
                 {
                     for(auto itl = it->second.begin(); itl != it->second.end(); ++itl)
                     {
                         cout<<' '<<*itl<<' ';
                     }
                     cout<<"987"<<'\n';
                 }
            
 
 
 
                /* for(map <string, list<string> > :: iterator p = data.begin(); p != data.end(); ++p)
                    p->second.sort();*/
     }
 
    void print (int mas[], int size) //ваще беда))
    {
        list<string> result;
        result.assign(all_stud.begin(), all_stud.end());
        map<string, list<string> > :: iterator p = data.begin();
 
        for_each(&mas[0], &mas[size],[&p, &result](int x)
        {
            if (x == 1)
            {
                list<string> help;
                set_intersection(result.begin(), result.end(), p->second.begin(), p->second.end(), back_inserter(help));                
                result.assign(help.begin(), help.end());
                ++p;
            }
            else
                if (x == -1)
                {
                    string help[40];
                    auto it = set_difference(result.begin(), result.end(), p->second.begin(), p->second.end(), help);
                    result.assign(help, it);
                    ++p;
                }
                else
                    ++p;
        });
        /*for(int i = 0; i<size; ++i)
        {
            if (mas[i] == 1)
            {
                string help[40];
                auto it = set_intersection(result.begin(), result.end(), p->second.begin(), p->second.end(), help);
                result.assign(help, it);
                ++p;
            }
            else
                if (mas[i] == -1)
                {
                    string help[40];
                    auto it = set_difference(result.begin(), result.end(), p->second.begin(), p->second.end(), help);
                    result.assign(help, it);
                    ++p;
                }
        }*/
        for(list<string> :: iterator l = result.begin(); l != result.end(); ++l)
            cout<< *l<<'\n';
        cout<<"\n";
    }
};
 
 
int _tmain(int argc, _TCHAR* argv[])
{
    setlocale(0, "Rus");
    const int n = 4;
    int mas[n] = {0,0,0,0};
 
    stud_file Stud("file.txt");
 
    cout<<"†††††††††††††††††††††††††††††††††††††††††††††\n";
    cout<<"Установите нужные параметры поиска\n";
    int con = 0;
    while (con !=-1)
    {
        cout<<"†††††††††††††††††††††††††††††††††††††††††††††\n";
        cout<<"биология       => 0\n";
        cout<<"математика     => 1\n";
        cout<<"физика         => 2\n";
        cout<<"химия          => 3\n";
        cout<<"текущий выбор  => 101\n";
        cout<<"вывести список => 102\n";
        cout<<"Выйти          => -1\n";
        cin >> con;
 
        switch (con)
        {
        case 0:
        case 1:
        case 2:
        case 3:
            {
                cout<<"изучает   =>1\n";
                cout<<"неважно   =>0\n";
                cout<<"неизучает =>-1\n";
                int i;
                cin>>i;
                mas[con] = i;
                break;
            }
        case 101:
            {
                for_each(&mas[0], &mas[n], [](int x){cout<<x<<' ';});
                cout<<"\n";
                break;
            }
        case 102:
            {
                Stud.print(mas,n);
            }
        }
    }
    return 0;
}
хочу разобраться именно с лямбда выражениями. Напомню - циклы использовать нельзя, а объект-функции просто не хочется
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
10.11.2011, 14:33
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Лямбда выражения (C++):

Лямбда-выражения и замыкание - C++
Здравствуйте, изучаю новый для себя стандарт языка и не совсем могу разобраться с замыканием Прогнал по отладчику - c изменяется...

С++11 Лямбда-выражения и вывод результата - C++
Поспорил с одним человеком, что смогу следующий код: alert( ); на C++ сделать (тоже просто). Решил использовать лямбда-выражения и C++11....

Что такое лямбда выражения? - C++
Объясните, пожалуйста, простым и человеческим языком, что такое лямбда выражения? Можно на примере печати двумерного вектора (часть...

Почему не работают лямбда-выражения? - C++
Почему не компилиться выводит 38 7 C:\Users\Administrator\Desktop\pjc6\z1-2\main.cpp 'lamMul' does not name a type ...

Использование лямбда выражения в качестве аргумента функции - C++
После того как я познакомился с ламбда функциями я хотел проверить их знания на некой практике, но я столкнулся с тем, что не знаю как...

Определение типа возвращаемого значения лямбда-выражения - C++
Вообщем не совсем понимаю в каких случаях надо использовать замыкающий тип возвращаемого выражения. У липпмана написано что данный пример...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
IcyWind
8 / 8 / 2
Регистрация: 19.09.2011
Сообщений: 269
10.11.2011, 15:08  [ТС] #16
C++
1
 for_each(data.begin(), data.end(), [](pair<string, list<string> > &p)
Добавлено через 1 минуту
Цитата Сообщение от ForEveR Посмотреть сообщение
IcyWind, Как ни странно for_each не предназначен для изменения контейнера. По лямбде можно. Если не получается - используйте алгоритмы который для этого предназначены. std::transform к примеру.
а да...наверно в этом всё дело
diagon
Higher
1929 / 1195 / 49
Регистрация: 02.05.2010
Сообщений: 2,925
Записей в блоге: 2
10.11.2011, 15:09 #17
Как предложили выше можно через transform.
C++
1
2
3
4
5
transform( data.begin(), data.end(), data.begin(), [] ( pair< string, list< string > > p)
{
   p.second.sort();
   return p;
} );
ForEveR
В астрале
Эксперт С++
7970 / 4732 / 321
Регистрация: 24.06.2010
Сообщений: 10,541
Завершенные тесты: 3
10.11.2011, 15:11 #18
IcyWind,
C++
1
std::transform(data.begin(), data.end(), data.begin(), [](std::pair<std::string, std::list<std::string>> elem) -> std::pair<std::string, std::list<std::string>> {elem.second.sort(); return elem;});
Добавлено через 39 секунд
diagon, Так не сработает насколько я помню.
diagon
Higher
1929 / 1195 / 49
Регистрация: 02.05.2010
Сообщений: 2,925
Записей в блоге: 2
10.11.2011, 15:12 #19
Цитата Сообщение от ForEveR Посмотреть сообщение
diagon, Так не сработает насколько я помню.
Хм... Почему? Из-за отсутствия -> ?
На gcc нормально компилируется.
ForEveR
В астрале
Эксперт С++
7970 / 4732 / 321
Регистрация: 24.06.2010
Сообщений: 10,541
Завершенные тесты: 3
10.11.2011, 15:14 #20
diagon, Значит я не прав.
diagon
Higher
1929 / 1195 / 49
Регистрация: 02.05.2010
Сообщений: 2,925
Записей в блоге: 2
10.11.2011, 15:16 #21
Цитата Сообщение от ForEveR Посмотреть сообщение
diagon, Значит я не прав.
Хех...
Нет, gcc хитрее.
Он оба варианта не компилирует >_<
До этого с вектором int'ов тестировал, все работало.
Пруф.
ForEveR
В астрале
Эксперт С++
7970 / 4732 / 321
Регистрация: 24.06.2010
Сообщений: 10,541
Завершенные тесты: 3
10.11.2011, 15:20 #22
diagon, Да... Мапа вроде создается как map<const Key, Value>...
talis
791 / 543 / 37
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
10.11.2011, 15:21 #23
diagon, что-то мне расхотелось обновляться до нового MinGW gcc 4.5.1 mingw компилирует for_each для std::list<int> с перезаписью каждого элемента ( [&counter]( int &e ){ e = counter++; } )
ForEveR
В астрале
Эксперт С++
7970 / 4732 / 321
Регистрация: 24.06.2010
Сообщений: 10,541
Завершенные тесты: 3
10.11.2011, 15:21 #24
Код
   *  Meets the requirements of a <a href="tables.html#65">container</a>, a
   *  <a href="tables.html#66">reversible container</a>, and an
   *  <a href="tables.html#69">associative container</a> (using unique keys).
   *  For a @c map<Key,T> the key_type is Key, the mapped_type is T, and the
   *  value_type is std::pair<const Key,T>.
Из сорцов.
talis
791 / 543 / 37
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
10.11.2011, 15:22 #25
ForEveR, точно. не подумал. прошу прощения, предыдущее сообщение бессмысленно.
diagon
Higher
1929 / 1195 / 49
Регистрация: 02.05.2010
Сообщений: 2,925
Записей в блоге: 2
10.11.2011, 15:24 #26
Цитата Сообщение от ForEveR Посмотреть сообщение
Из сорцов.
Но если изменить string на const string, то ничего не изменится...
IcyWind
8 / 8 / 2
Регистрация: 19.09.2011
Сообщений: 269
10.11.2011, 15:26  [ТС] #27
вообщем vs на всё ругается, и на &p, и на transform, ибо
C++
1
1>c:\program files (x86)\microsoft visual studio 10.0\vc\include\utility(260): error C2678: бинарный "=": не найден оператор, принимающий левый операнд типа "const std::string" (или приемлемое преобразование отсутствует)
щас уже нет время - нужно бежать, а вечером ещё вернусь к этому...
ForEveR
В астрале
Эксперт С++
7970 / 4732 / 321
Регистрация: 24.06.2010
Сообщений: 10,541
Завершенные тесты: 3
10.11.2011, 15:37 #28
diagon, Где изменить? Разыменованный итератор для мапы возвращает value_type то есть pair<const Key, Value>.

Добавлено через 4 минуты
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
#include <iostream>
#include <string>
#include <map>
#include <list>
#include <algorithm>
#include <iterator>
 
int main()
{
   std::list<std::string> lst = {"hello", "and", "what"};
   std::map<std::string, std::list<std::string>> data = {make_pair("hello", lst)};
   std::for_each(data.begin(), data.end(), [&data]
   (std::map<std::string, std::list<std::string>>::value_type value)
   {
      data.erase(value.first);
      value.second.sort();
      data.insert(value);
   });
   std::for_each(data.begin(), data.end(),
   [](const std::map<std::string, std::list<std::string>>::value_type& value)
   {
      std::cout << "Key: " << value.first << std::endl;
      std::cout << "Values: " << std::endl;
      std::copy(value.second.begin(), value.second.end(),
      std::ostream_iterator<std::string>(std::cout, "\n"));
   });
}
Как вариант.

Добавлено через 37 секунд
http://liveworkspace.org/code/380380...8af593973a0871
diagon
Higher
1929 / 1195 / 49
Регистрация: 02.05.2010
Сообщений: 2,925
Записей в блоге: 2
10.11.2011, 15:37 #29
Цитата Сообщение от ForEveR Посмотреть сообщение
diagon, Где изменить? Разыменованный итератор для мапы возвращает value_type то есть pair<const Key, Value>.
Везде
http://liveworkspace.org/code/d40aa7...00e199f9522f71
И вообще, я думал, что если не указывать тип возвращаемого значения, то компилятор сам его подберет.
ForEveR
В астрале
Эксперт С++
7970 / 4732 / 321
Регистрация: 24.06.2010
Сообщений: 10,541
Завершенные тесты: 3
10.11.2011, 15:41 #30
diagon, Алгоритм transform делает ничто иное как:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
  template<typename _InputIterator, typename _OutputIterator,
       typename _UnaryOperation>
    _OutputIterator
    transform(_InputIterator __first, _InputIterator __last,
          _OutputIterator __result, _UnaryOperation __unary_op)
    {
      // concept requirements
      __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
      __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
            // "the type returned by a _UnaryOperation"
            __typeof__(__unary_op(*__first))>)
      __glibcxx_requires_valid_range(__first, __last);
 
      for (; __first != __last; ++__first, ++__result)
    *__result = __unary_op(*__first);
      return __result;
    }
Где в данном случае __result - итератор мапы. И возвращаемое значение оператора * у итератора мапы является map::value_type, где map::value_type == pair<const Key, Value>.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
10.11.2011, 15:41
Привет! Вот еще темы с ответами:

Лямбда функции - C++
Всем добрый вечер! Пытаюсь ознакомиться поближе с лямбда функциями и уже возникли трудности... Просмотрела пару публикаций на эту тему и...

лямбда функция - C++
привет всем! не понимаю в чем ошибка...вот код vector&lt;string&gt; tmp_count; list&lt;string&gt; tmp_result = str; for(auto i =...

Рекурсивная лямбда - C++
можно ли в лямбде сделать рекурсию? как получить имя безымянной функции? this не пашет...

Max_element с лямбда-функцией - C++
Интереса ради решил попробовать такую конструкцию string s; getline(cin,s); auto ma=max_element(s.begin(),s.end(),(string...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
10.11.2011, 15:41
Ответ Создать тему
Опции темы

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