МАРК РЕГНЕРУС ДОСЛІДЖЕННЯ: Наскільки відрізняються діти, які виросли в одностатевих союзах
РЕЗОЛЮЦІЯ: Громадського обговорення навчальної програми статевого виховання ЧОМУ ФОНД ОЛЕНИ ПІНЧУК І МОЗ УКРАЇНИ ПРОПАГУЮТЬ "СЕКСУАЛЬНІ УРОКИ" ЕКЗИСТЕНЦІЙНО-ПСИХОЛОГІЧНІ ОСНОВИ ПОРУШЕННЯ СТАТЕВОЇ ІДЕНТИЧНОСТІ ПІДЛІТКІВ Батьківський, громадянський рух в Україні закликає МОН зупинити тотальну сексуалізацію дітей і підлітків Відкрите звернення Міністру освіти й науки України - Гриневич Лілії Михайлівні Представництво українського жіноцтва в ООН: низький рівень культури спілкування в соціальних мережах Гендерна антидискримінаційна експертиза може зробити нас моральними рабами ЛІВИЙ МАРКСИЗМ У НОВИХ ПІДРУЧНИКАХ ДЛЯ ШКОЛЯРІВ ВІДКРИТА ЗАЯВА на підтримку позиції Ганни Турчинової та права кожної людини на свободу думки, світогляду та вираження поглядів Контакти
Тлумачний словник |
|
|||||||
Об’єкти-функціїФункція accumulate, розглянута у попередньому пункті, є дуже загальною з погляду використання ітераторів, але вона є недостатньо загальною щодо прийнятих у ній припущень про типи значень, на які посилаються ітератори (вони називаються типами значень ітераторів). У визначенні функції accumulate використовуються вирази init = init + *first++; за припущення, що в типі значень визначена операція +. Тому ця функція може використовуватися для вбудованих числових типів мови С++, а також для довільного типу Т, визначеного користувачем, в якому визначена операція +, щоб додавати значення елементів послідовності. Але абстрактний зміст нагромадження (accumulate) застосовується не лише до підсумовування. Можна, наприклад, нагромаджувати добуток значення елементів послідовності. Тому STL пропонує іншу, загальнішу версію функції accumulate: template <class InputIterator, class T, class BinaryOperation>; T accumulate(InputIterator first, InputIterator last, T init, BinaryOperation binary_op) { while (first != last) init = binary_op(init,*first++); return init; } У цьому визначенні вводиться ще один параметр, binary_op, який використовується замість + та визначає бінарну операцію, застосовувану для об’єднання значень. Застосовування нової версії функції accumulate ілюструється таким прикладом: #include <vector.h> #include <algo.h> #include <assert.h> int mult(int x, int y){return x*y;} int main() { cout<< «Використання параметричної функції accumulate» <<«для обчислення добутку»<< end1; int x[5] = {2,3,5,7,11}; //ініціалізація вектора vector1 значенням від x[0] до x[4] vector<int> vector1(x,x+5); int product = accumulate(vector1.begin(),vector1.end(),1,mult); assert(product == 2310); } (Зауважимо, що у програмі початкове значення (init) замінено з 0 на 1). Тут як accumulate використовується звичайна функція, але в мові С++ підтримується й інша можливість: передача об’єкта-функції; об’єктом-функцією у STL називається об’єкт, тип якого визначено як клас (або структура), членом якого є операція виклику функції operator( ). У наведеному далі прикладі показана найпростіша форма об’єкта-функції: #include <vector.h> #include <algo.h> #include <assert.h> class multiply{ public: int operator()(int x, int y)const{return x*y;} }; int main() { cout<< «Використання параметричної функції accumulate» <<«для обчислення добутку»<< end1; int x [5] = {2,3,5,7,11}; //ініціалізація вектора vector1 значенням від x[0] до x[4] vector<int> vector1(x,x+5); int product = accumulate(vector1.begin(), vector1.end(), 1, multiply()); assert (product == 2310); } Визначення операції виклику функції operator( ) в класі multiply породжує об’єкт, який може бути застосований у списку параметрів точно так, як і функція. Зазначимо, що об’єкт, переданий як третій параметр функції accumulate, утворюється за допомогою (неявного) конструктора multiply( ) класу multiply. Зауважимо також, що цей об’єкт не має зв’язаної з ним пам’яті аналогічно визначенню функції. У чому ж полягає перевага об’єктів-функцій над звичайними функціями? На відміну від звичайних функцій об’єктам-функціям може бути повідомлена додаткова інформація, яка може бути використана параметричними алгоритмами чи контейнерами, коли їм знадобиться складніша інформація про властивості функції. Крім того, виклики об’єктів-функцій звичайно змінюються компілятором С++ на прямі текстуальні вставки, що забезпечує велику ефективність у їх використанні (економиться час на виклик функції). Зауважимо також, що у прикладі можна було б не визначати клас multiply, оскільки у STL існує таке визначення, щоправда, у загальнішій формі: template<class T> class times: public binary_function<T,T,T>{ public: T operator()(const T& x, const T& y) const{ return x*y; } }; Цей клас наслідує другому компоненту STL класу binary_function, мета введення якого — забезпечити сховище додатковою інформацією про функції. Використовуючи це визначення, можна переписати попередній приклад так: #include <vector.h> #include <algo.h> #include <assert.h> int main() { cout<< «Використання параметричної функції accumulate» <<«для обчислення добутку»<< end1; int x[5] = {2,3,5,7,11}; //ініціалізація вектора vector1 значенням від x[0] до x[4] vector<int> vector1(x,x+5); int product = accumulate(vector1.begin(), vector1.end(), 1, times<int>()); assert(product = = 2310); } Клас times визначено у файлі-заголовку function.h, який вже вставлено у програму у складі algo.h. times<int>( ), що є звертанням до (неявного) конструктора класу times з типом int.
|
||||||||
|