Форум программистов, компьютерный форум, киберфорум
Наши страницы

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

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

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

10.11.2011, 14:33. Просмотров 4129. Ответов 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;
}
хочу разобраться именно с лямбда выражениями. Напомню - циклы использовать нельзя, а объект-функции просто не хочется
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++
Вообщем не совсем понимаю в каких случаях надо использовать замыкающий тип возвращаемого выражения. У липпмана написано что данный пример...

31
diagon
Higher
1932 / 1198 / 49
Регистрация: 02.05.2010
Сообщений: 2,925
Записей в блоге: 2
10.11.2011, 14:35 #2
Цитата Сообщение от IcyWind Посмотреть сообщение
[](pair<string, list<string> > p)
Передается по значению, т.е. создается новый объект.
Передавайте по ссылке
C++
1
pair<string, list<string> > &p
Еще лучше нормальный foreach использовать
C++
1
2
for ( auto &p : data )
  p.second.sort();
1
talis
792 / 544 / 37
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
10.11.2011, 14:44 #3
А если так?

C++
1
2
3
4
[](pair<string, list<string> > &p)
                                 {
                                         p.second.sort();
                                 }
Добавлено через 22 секунды

Не по теме:

пока читал, опоздал :-)



Добавлено через 2 минуты

Не по теме:

diagon, эх жаль, что мой gcc не понимает этот новый for. Красиво.

0
diagon
Higher
1932 / 1198 / 49
Регистрация: 02.05.2010
Сообщений: 2,925
Записей в блоге: 2
10.11.2011, 14:47 #4
Цитата Сообщение от talis Посмотреть сообщение
diagon, эх жаль, что мой gcc не понимает этот новый for. Красиво.
А мой понимает
Bash
1
2
3
4
5
6
diagon@shadeware:~$ g++ --version
g++ (Ubuntu/Linaro 4.6.1-9ubuntu3) 4.6.1
Copyright (C) 2011 Free Software Foundation, Inc.
Это свободно распространяемое программное обеспечение. Условия копирования
приведены в исходных текстах. Без гарантии каких-либо качеств, включая 
коммерческую ценность и применимость для каких-либо целей.
Только я компилирую с ключом -std=c++0x. Без него не работает.
0
talis
792 / 544 / 37
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
10.11.2011, 14:49 #5
diagon, я тоже с ключом. Просто я в основном под mingw сейчас сижу, давно не обновлял
0
IcyWind
8 / 8 / 2
Регистрация: 19.09.2011
Сообщений: 272
10.11.2011, 14:53  [ТС] #6
Цитата Сообщение от diagon Посмотреть сообщение
Передается по значению, т.е. создается новый объект, копирующий старый.
Передавайте по ссылке
C++
1
pair<string, list<string> > &p
нет, это строчка - аналог operator ()
for_each делает (*p)
список передаваемых параметров заключён в [], но я не передаю параметр
компилятор создаёт какую-то функцию, с каким-то именем, а то, что написано в () в моей записи - это аналог operator() для созданной компилятором объект-функции
и тогда запись
C++
1
pair<string, list<string> > &p
приведёт к ошибке компиляции - не соответствие типов
0
diagon
Higher
1932 / 1198 / 49
Регистрация: 02.05.2010
Сообщений: 2,925
Записей в блоге: 2
10.11.2011, 14:56 #7
Цитата Сообщение от IcyWind Посмотреть сообщение
нет, это эта строчка - аналог operator ()
Эта строчка - список аргументов.
Сравните сами
По значению - http://liveworkspace.org/code/c84dec95148b49458c64f0eb121eaf0d
По ссылке - http://liveworkspace.org/code/a490b330585cabff482567712fa79e1a
(Вывод внизу)
0
ForEveR
В астрале
Эксперт С++
7983 / 4742 / 321
Регистрация: 24.06.2010
Сообщений: 10,547
Завершенные тесты: 3
10.11.2011, 14:58 #8
IcyWind, Нет. Передавать параметр надо по ссылке. Конструкция [] (type param) ничто иное как передача параметров. Передавайте по ссылке и все будет ок.
0
IcyWind
8 / 8 / 2
Регистрация: 19.09.2011
Сообщений: 272
10.11.2011, 14:58  [ТС] #9
Цитата Сообщение от ForEveR Посмотреть сообщение
IcyWind, Нет. Передавать параметр надо по ссылке. Конструкция [] (type param) ничто иное как передача параметров. Передавайте по ссылке и все будет ок.
C++
1
1>c:\program files (x86)\microsoft visual studio 10.0\vc\include\algorithm(22): error C2664: void `anonymous-namespace'::<lambda0>::operator ()(std::pair<_Ty1,_Ty2> &) const: невозможно преобразовать параметр 1 из "std::pair<_Ty1,_Ty2>" в "std::pair<_Ty1,_Ty2> &"
ну и?
0
talis
792 / 544 / 37
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
10.11.2011, 15:02 #10
IcyWind, в gcc всё ок. vs 10 тупит. а вообще выложите строчки, выдающие ошибку.
0
diagon
10.11.2011, 15:03
  #11

Не по теме:

Цитата Сообщение от IcyWind Посмотреть сообщение
C++
1
1>c:\program files (x86)\microsoft visual studio 10.0\vc\include\algorithm(22): error C2664: void `anonymous-namespace'::<lambda0>::operator ()(std::pair<_Ty1,_Ty2> &) const: невозможно преобразовать параметр 1 из "std::pair<_Ty1,_Ty2>" в "std::pair<_Ty1,_Ty2> &"
ну и?
Студия такая студия...

0
IcyWind
8 / 8 / 2
Регистрация: 19.09.2011
Сообщений: 272
10.11.2011, 15:04  [ТС] #12
ошибка тут
C++
1
2
3
4
5
6
7
8
template<class _InIt,
    class _Fn1> inline
    _Fn1 _For_each(_InIt _First, _InIt _Last, _Fn1 _Func)
    {   // perform function for each element
    for (; _First != _Last; ++_First)
        _Func(*_First);
    return (_Func);
    }
описание
C++
1
1>c:\program files (x86)\microsoft visual studio 10.0\vc\include\algorithm(22): error C2664: void `anonymous-namespace'::<lambda0>::operator ()(std::pair<_Ty1,_Ty2> &) const: невозможно преобразовать параметр 1 из "std::pair<_Ty1,_Ty2>" в "std::pair<_Ty1,_Ty2> &"
0
silent_1991
10.11.2011, 15:04
  #13

Не по теме:

Цитата Сообщение от talis Посмотреть сообщение
мой gcc не понимает этот новый for
В чём проблема обновить?

0
ForEveR
В астрале
Эксперт С++
7983 / 4742 / 321
Регистрация: 24.06.2010
Сообщений: 10,547
Завершенные тесты: 3
10.11.2011, 15:05 #14
IcyWind, Как ни странно for_each не предназначен для изменения контейнера. По лямбде можно. Если не получается - используйте алгоритмы который для этого предназначены. std::transform к примеру.
1
talis
792 / 544 / 37
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
10.11.2011, 15:06 #15
IcyWind, да не вырезку из стандартной библиотеки. Строчку, которая породила ошибку.

Не по теме:

silent_1991, нужна была причина. Теперь есть причина

0
10.11.2011, 15:06
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
10.11.2011, 15:06
Привет! Вот еще темы с ответами:

Лямбда функции - 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...


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

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

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