templates c with examples
Вивчіть різні аспекти шаблонів на C ++.
Шаблони - одна з найпотужніших функцій на C ++. Шаблони надають нам код, який не залежить від типу даних.
Іншими словами, використовуючи шаблони, ми можемо написати загальний код, який працює для будь-якого типу даних. Нам просто потрібно передати тип даних як параметр. Цей параметр, який передає тип даних, також називається ім'ям типу.
У цьому підручнику ми детально вивчимо все про шаблони та їх різні аспекти.
=> Клацніть тут, щоб переглянути абсолютну серію навчальних програм C ++.
Що ви дізнаєтесь:
- Що таке шаблони?
- Як користуватися шаблонами / реалізацією?
- typename Vs. ключове слово класу
- Втілення шаблону та спеціалізація
- Спеціалізація шаблону
- Варіадичні шаблони C ++
- Висновок
- Рекомендована література
Що таке шаблони?
Як зазначалося вище, шаблони є загальними, тобто не залежать від типу даних. Шаблони використовуються головним чином для забезпечення повторного використання коду та гнучкості програм. Ми можемо просто створити просту функцію або клас, який приймає тип даних як параметр, і реалізувати код, який працює для будь-якого типу даних.
Наприклад, якщо ми хочемо, щоб алгоритм сортування працював для всіх числових типів даних, а також рядків символів, тоді ми просто напишемо функцію, яка приймає тип даних як аргумент, і реалізуємо техніку сортування.
Тоді, залежно від типу даних (ім’я типу), який передається алгоритму сортування, ми можемо сортувати дані незалежно від типу даних. Таким чином, нам не потрібно писати десять алгоритмів для десяти типів даних.
Таким чином, шаблони можуть бути використані в додатках, де ми вимагаємо, щоб код використовувався для більш ніж одного типу даних. Шаблони також використовуються в додатках, де повторне використання коду має першочергове значення.
Як користуватися шаблонами / реалізацією?
Шаблони можуть бути реалізовані двома способами:
що таке tdd і bdd (огірковий каркас)
- Як шаблон функції
- Як шаблон класу
Шаблон функції
Шаблон функції подібний до звичайної функції, але єдина відмінність полягає в тому, що звичайна функція може працювати лише з одним типом даних, а код шаблону функції може працювати з кількома типами даних.
Хоча ми можемо фактично перевантажити звичайну функцію для роботи з різними типами даних, шаблони функцій завжди є більш корисними, оскільки нам доводиться писати єдину програму, і вона може працювати на всіх типах даних.
Далі ми побачимо реалізацію шаблонів функцій.
Загальний синтаксис шаблону функції:
template T function_name(T args){ …… //function body }
Тут T - аргумент шаблону, який приймає різні типи даних, а клас - ключове слово. Замість класу ключових слів ми можемо також написати ‘typename’.
Коли певний тип даних передається в function_name, компілятор робить копію цієї функції з цим типом даних як аргументом і виконується функція.
Давайте подивимось приклад для кращого розуміння шаблонів функцій.
#include using namespace std; template void func_swap(T &arg1, T &arg2) { T temp; temp = arg1; arg1 = arg2; arg2 = temp; } int main() { int num1 = 10, num2 = 20; double d1 = 100.53, d2 = 435.54; char ch1 = 'A', ch2 = 'Z'; cout << 'Original data
'; cout << 'num1 = ' << num1 << ' num2 = ' << num2<Шаблони класів Як і в шаблонах функцій, ми можемо мати вимогу мати клас, подібний до всіх інших аспектів, але лише різних типів даних.
У цій ситуації ми можемо мати різні класи для різних типів даних або різну реалізацію для різних типів даних в одному класі. Але це зробить наш код громіздким.
Найкращим рішенням для цього є використання класу шаблонів. Клас шаблону також поводиться подібно до шаблонів функцій. Нам потрібно передати клас даних як параметр класу під час створення об'єктів або виклику функцій-членів.
Загальний синтаксис для шаблону класу:
template class className{ ….. public: T memVar; T memFunction(T args); };
У наведеному вище визначенні T виступає як заповнювач для типу даних. Громадські учасники memVar та memFunction також використовують T як заповнювач для типів даних.
Як тільки клас шаблону визначений, як зазначено вище, ми можемо створювати об'єкти класу наступним чином:
className classObejct1; className classObject2; className classObject3;
Давайте реалізуємо приклад коду для демонстрації шаблонів класів:
#include using namespace std; template class myclass { T a, b; public: myclass (T first, T second) {a=first; b=second;} T getMaxval (); }; template T myclass::getMaxval () { return (a>b? a : b); } int main () { myclass myobject (100, 75); cout<<'Maximum of 100 and 75 = '< Вихід:
Максимум 100 і 75 = 100
Максимум 'A' та 'a' = a
Вищевказана програма реалізує приклад шаблону класу. У нас є шаблон класу myclass. Всередині цього ми маємо конструктор, який ініціалізує два члени класу a і b. Існує ще одна функція-член getMaxval, яка також є шаблоном функції, що повертає максимум a та b.
У головній функції ми будуємо два об'єкти, myobject цілого типу і mychobject символу типу. Потім ми викликаємо функцію getMaxval для кожного з цих об’єктів, щоб визначити максимальне значення.
Зауважте, що крім параметрів типу шаблону (параметри типу T), функції шаблону можуть також мати звичайні параметри, такі як звичайні функції, а також значення параметрів за замовчуванням.
typename Vs. ключове слово класу
Оголошуючи клас або функцію шаблону, ми використовуємо одне з двох ключових слів клас або ім'я типу. Ці два слова є семантично еквівалентними і можуть використовуватися як взаємозамінні.
Запитання та відповіді на інтерв’ю j2ee для старших розробників
Але в деяких випадках ми не можемо використовувати ці слова як еквівалентні. Наприклад, коли ми використовуємо залежні типи даних у шаблонах, таких як “typedef”, ми використовуємо typename замість класу.
Крім того, ключове слово class має використовуватися, коли нам потрібно явно створити екземпляр шаблону.
Втілення шаблону та спеціалізація
Шаблони написані загальним чином, що означає, що це загальна реалізація незалежно від типу даних. Відповідно до наданого типу даних, нам потрібно створити конкретний клас для кожного типу даних.
Наприклад, якщо у нас є алгоритм сортування шаблону, ми можемо створити конкретний клас для сортування, інший клас для сортування тощо. Це називається створенням екземпляра шаблону.
Ми підставляємо аргументи шаблону (фактичні типи даних) для параметрів шаблону у визначенні класу шаблону.
Наприклад,
template class sort {};
Коли ми передаємо тип даних, компілятор замінює тип даних на „T“ так, що алгоритм сортування стає сортуванням.
Кожного разу, коли ми використовуємо клас або функцію шаблону, виникає потреба в екземплярі, коли ми передаємо певний тип даних. Якщо цього екземпляра ще немає, компілятор створює такий із певним типом даних. Це неявний екземпляр.
Одним недоліком неявного екземпляру є те, що компілятор генерує клас екземпляра лише для аргументів, які використовуються в даний час. Це означає, що якщо ми хочемо створити бібліотеку екземплярів перед використанням цих екземплярів, нам потрібно піти на явний екземпляр.
Приклад оголошення шаблону наведено нижче:
template class Array(T)
Можна явно інстанціювати як:
template class Array
Коли інстанціюється клас, усі його члени також створюються.
Спеціалізація шаблону
Під час програмування за допомогою шаблонів ми можемо зіткнутися з такою ситуацією, що нам може знадобитися спеціальна реалізація для певного типу даних. Коли така ситуація трапляється, ми йдемо на спеціалізацію з шаблонів.
У спеціалізації шаблонів ми реалізуємо особливу поведінку для певного типу даних, крім вихідного визначення шаблону для інших типів даних.
Наприклад, вважаємо, що у нас є шаблонний клас myIncrement ’ який має конструктор для ініціалізації значення та функції шаблону toIncrement що збільшує значення на 1.
Цей конкретний клас буде чудово працювати для всіх типів даних, крім char. Замість того, щоб збільшувати значення для char, чому б не надати йому особливої поведінки та замість цього перетворити символ у верхній регістр?
Для цього ми можемо піти на спеціалізацію шаблону для типу даних char.
Ця реалізація показана в наведеному нижче прикладі коду.
#include using namespace std; // class template: template class myIncrement { T value; public: myIncrement (T arg) {value=arg;} T toIncrement () {return ++value;} }; // class template specialization: template class myIncrement { char value; public: myIncrement (char arg) {value=arg;} char uppercase () { if ((value>='a')&&(value<='z')) value+='A'-'a'; return value; } }; int main () { myIncrement myint (7); myIncrement mychar ('s'); myIncrement mydouble(11.0); cout<<'Incremented int value: '<< myint.toIncrement()<< endl; cout<<'Uppercase value: '< Вихід:
Збільшене значення int: 8
Велике регістр: S
Збільшене подвійне значення: 12

У наведеній вище програмі, яка демонструє спеціалізацію шаблонів, подивіться, як ми оголосили спеціалізований шаблон для типу char. Спочатку ми оголошуємо оригінальний клас, а потім «спеціалізуємо» його на типі char. Для початку спеціалізації ми використовуємо порожню декларацію шаблону “шаблон”.
Потім після назви класу ми включаємо тип даних. Після цих двох змін клас пишеться для типу char.
У головній функції зауважте, що немає різниці між інстанціюванням типу char та іншими типами. Різниця лише в тому, що ми перевизначаємо спеціалізований клас.
Зверніть увагу, що ми повинні визначити всіх членів спеціалізованого класу, хоча вони абсолютно однакові в загальному / оригінальному класі шаблону. Це тому, що у нас немає функції успадкування для членів від загального шаблону до спеціалізованого шаблону.
Варіадичні шаблони C ++
Дотепер ми бачили шаблони функцій, які приймають фіксовану кількість аргументів. Існують також шаблони, що беруть змінну кількість аргументів. Ці шаблони функцій називаються варіадичними шаблонами. Варіадичні шаблони - одна з найновіших функцій C ++ 11.
Варіадичні шаблони беруть змінну кількість аргументів, які захищають тип, і аргументи вирішуються під час компіляції.
Візьмемо повний приклад програмування, щоб зрозуміти це.
#include #include using namespace std; template T summation(T val) { return val; } template T summation(T first, Args... args) { return first + summation(args...); } int main() { long sum = summation(1, 2, 3, 8, 7); cout<<'Sum of long numbers = '< Наведений приклад демонструє варіатичну функцію, “підсумовування”. Як показано вище, нам спочатку потрібна базова функція, яка реалізує базовий випадок. Потім ми реалізуємо варіадичну функцію вгорі цієї функції.
У підсумовуванні змінної функції називається “typename… args” пакет параметрів шаблону тоді як 'Args ... args' називається пакет параметрів функції .
Після написання шаблону функції, який реалізує базовий випадок, ми пишемо варіадичну функцію, яка реалізує загальний випадок. Варіадична функція записується подібно до рекурсії, як показано для підсумовування (аргументи ...). Перший аргумент відокремлюється від набору параметрів функції у тип T (перший).
Як переглянути файли XML в
З кожним викликом підсумовування список параметрів звужується на один аргумент і зрештою досягається базова умова. Результат показує підсумовування довгих цілих чисел і символів.
Висновок
На цьому ми закінчуємо цей посібник із шаблонів на C ++. Шаблони допомагають нам зробити наші програми загальними, тобто незалежними від типу.
Також читайте = >> Підручник з шаблону колби
Загальні програми завжди стоять поверх інших програм, оскільки нам не потрібно писати окремі програми для кожного типу даних. Таким чином, розробка загально безпечних програм може бути важливим кроком на шляху до ефективного програмування.
=> Ознайомтесь із поглибленими навчальними посібниками для C ++ тут.
Рекомендована література
- Підручник з основних функцій Python з практичними прикладами
- Як працює тестування на основі даних (приклади QTP та селену)
- Багатопотоковість на C ++ з прикладами
- Підручник з Python DateTime із прикладами
- Зразок шаблону тестового кейсу з прикладами тестового кейсу (Завантажити)
- Вирізати команду в Unix з прикладами
- Зразок шаблону для звіту про прийомні випробування з прикладами
- Синтаксис команд Unix Cat, варіанти з прикладами