1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
//C++ Листинг 1.1 Обход массива [] c помощью for_each #include <iostream> #include <algorithm> //Обозначаем, что будем использовать алгоритмы using namespace std; void show(int i) //Функция, которая будет передаваться в алгоритм { cout << i << '\n'; //выводим значение пришедшего параметра i на экран } int main() { int M[] = {1,2,3,4,5}; //Обычный массив int len = sizeof(M)/sizeof(M[0]); //число элементов в массиве for_each(M,M+len,show); //алгоритм } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
//C++ Литсинг 1.2 Обход массива std::array c помощью for_each #include <iostream> #include <algorithm> //Обозначаем, что будем использовать алгоритмы #include <array> using namespace std; void show(int i) //Функция, которая будет передаваться в алгоритм { cout << i << '\n'; //выводим значение пришедшего параметра i на экран } int main() { const size_t len = 5; array<int, len> M = {1,2,3,4,5}; //массив std::array for_each(M.begin(),M.end(),show); //алгоритм, указание границ через итераторы } |
1 2 3 |
//К листингу #1.2 for_each(M.begin(),M + len,show); //ошибка: M не преобразовывается в указатель for_each(M.begin(),M.begin() + len,show); //OK |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
//C++ Листинг 1.3 Обход массива std::array c помощью for_each функция std::begin и std::end работают с массивами #include <iostream> #include <algorithm> //Обозначаем, что будем использовать алгоритмы #include <array> using namespace std; void show(int i) //Функция, которая будет передаваться в алгоритм { cout << i << '\n'; //выводим значение пришедшего параметра i на экран } int main() { const size_t len = 5; int arr[] = {1,2,3,4,5}; //массив [] for_each(begin(arr),end(arr),show); //алгоритм, указание границ через итераторы } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
//C++ Листинг 1.4 Обход массива std::array c помощью for_each функция std::begin и std::end не работают с указателями #include <iostream> #include <algorithm> //Обозначаем, что будем использовать алгоритмы #include <array> using namespace std; void show(int i) //Функция, которая будет передаваться в алгоритм { cout << i << '\n'; //выводим значение пришедшего параметра i на экран } int main() { const size_t len = 5; int *arr = new int[len]{1,2,3,4,5}; //указатель на массив (не массив!) for_each(begin(arr),end(arr),show); //ошибка! } |
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 |
//C++ Литсинг 2.1 for_each #include <iostream> #include <algorithm> //Обозначаем, что будем использовать алгоритмы using namespace std; void show(int i) //Функция, которая будет передаваться в алгоритм { cout << i << '\n'; //выводим значение пришедшего параметра i на экран } void pow(int &i){ //будем value привавлять к значению массива i = i * i; } int main() { int M[] = {1,2,3,4,5}; //Обычный массив int len = sizeof(M)/sizeof(M[0]); //число элементов в массиве cout << "before: \n"; for_each(M,M+len,show); //алгоритм (выводим значения на экран) for_each(M,M+len,pow); //алгоритм (изменяем каждый элемент возведением в степень) cout << "after: \n"; for_each(M,M+len,show); //алгоритм (выводим значения на экран) } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
//C++ Литсинг 2.3 for_each — это немодифицирующий алгоримт #include <iostream> #include <algorithm> //Обозначаем, что будем использовать алгоритмы using namespace std; void summ(int &i, const int value){ i = i+value; } int main() { auto M = {1, 2, 3, 4, 5}; for_each(M.begin(),M.end(),summ); //никак нельзя передать value, foreach подхватывает только и только функцию с одним параметром (сейчас у summ два параметра) } |
возвращает функцию, которую принимает третьим параметром (здесь это foo, а it1, it2 — это условное обозначение итераторов). Т. е. если мы подаём foo как функцию-обработик, то результат foo можно вытащить, используя полное выражение
как функцию.
1 2 3 4 5 6 7 8 9 10 11 12 |
//Листинг 3.1 int foo(int){ //функция обработчик return 123; //только для примера просто возвращаем результат } int main(){ vector<int> v{1,2,3,4,5); for_each(v.begin(),v.end(), foo)(777); //Полное выражение — это то же, что вызов foo(777) } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
//C++ Листинг 3.2 for_each и возвращаемые значения #include <iostream> using namespace std; int foo(const int value){ return value + 5; } int main() { auto M = {1, 2, 3, 4, 5, 7, 7, 1}; //какой-нибудь массив int result = for_each(M.begin(),M.end(),foo)(-1); cout << result; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
//C++ Листинг 3.3 for_each и возвращаемые значения #include <iostream> using namespace std; int foo(const int value){ //Функция обработки: отдаётся в третий аргумент при вызове и //возвращается как результат выражения for_each(...)(value) static int result = 0; if (!(value % 2)) { cout << value << '\n'; //для наглядности result++; } return result; } int main() { auto M = {1, 2, 3, 4, 5, 7, 7, 1}; //какой-нибудь массив int result = for_each(M.begin(),M.end(),foo)(0); } |
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 |
//C++ Листинг 3.4 for_each и возвращаемые значения #include <iostream> using namespace std; class MyFunctor{ int result = 0; public: void operator ()(const int value){ if (value % 2){ result++; } } int get_result() { return result; } }; int main() { auto M = {1, 2, 3, 4, 5, 7, 7, 1}; //какой-нибудь массив MyFunctor mf; int result = for_each(M.begin(),M.end(),mf).get_result(); //6 нечетных чисел cout << result << '\n'; } |
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 |
//C++ Листинг #4.1 Использование функтора в for_each #include <iostream> #include <algorithm> //Обозначаем, что будем использовать алгоритмы #include <vector> using namespace std; struct MyClass { //(функтор): void operator() (int i) //перегруженные в классе скобки делают объектs этого класса функторами, //т. е. объекты можно будет задействовать в синтаксисе как функции { std::cout << " " << i; } }; int main() { MyClass obj; //Объявили объект типа MyClass vector <int> v; v.push_back(1); v.push_back(2); v.push_back(3); v.push_back(4); for_each(v.begin(),v.end(),obj); //использовали объект в качестве аргумента для алгоритма cout<<"\n"; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
//C++ Листинг #5.1 Использование лямбда-выражения в for_each #include <iostream> #include <algorithm> //Обозначаем, что будем использовать алгоритмы #include <vector> using namespace std; int main() { vector <int> v; v.push_back(1); v.push_back(2); v.push_back(3); v.push_back(4); for_each(v.begin(),v.end(),[](int i){ cout << i << '\n';}); //использовали объект в качестве аргумента для алгоритма cout<<"\n"; } |
void operator () ( int i) пожалуйста обисните
эту строчку. (int i)-здес параметр что ли?
void operator () ( int i) принимает параметр типа int и печатает его на экран.
void — нет возвращаемого значения.
void operator () ( int i)
это перегрузка скобок, что бы после объявления объекта obj, можно было ему передать в скобках аргумент, иначе в скобках можно передать при объявлении.
Это ФУНКТОР! Структура состоит только из функции(перегруженного оператора вызова скобок функции)! void operator() (int i) нужен для того, чтоб когда пишешь obj, тоесть вызываешь обьект этой структуры, то срабатывает перегрузка оператора скобки и тем самым вызыватся функция! Вроде так…если нет то поправьте)
😥
каким образом происходит передача параметра «i» в функтор?
в прототипе for_each — принимается только укзатель на функтор но, нет нигде ссылки на аргумент, вызываемой функции (функтора)
Возможно, эта статья поможет это понять: С++ для начинающих. Коллбек.
можно ли присвоить for_each какой либо переменной. Например я хочу посчитать сумму нечетных элементов в векторе, могу ли я прописать функцию для определения четности числа, сделать данную функцию не воид, а int и передать как 3 параметр for_each. После написать int sum += for_each(vector.begin(), vector.end(), poiskchet);
Посчитать число элементов и сохранить результат в переменную посредством for_each можно, но для выполнения задачи счёта_с_условием следует использовать count_if.
Если хочется повыделываться, то сделать это можно так: