templates c with examples
Научете различните аспекти на шаблоните в C ++.
Шаблоните са една от най-мощните функции в C ++. Шаблоните ни предоставят кода, който е независим от типа данни.
С други думи, използвайки шаблони, можем да напишем общ код, който работи за всеки тип данни. Просто трябва да предадем типа данни като параметър. Този параметър, който предава типа данни, се нарича още име на тип.
В този урок ще разгледаме подробно всичко за шаблоните и различните му аспекти.
=> Щракнете тук за абсолютната серия за обучение на C ++.
Какво ще научите:
- Какво представляват шаблоните?
- Как да използвам шаблони / внедряване?
- typename Vs. ключова дума за клас
- Инстантиране на шаблони и специализация
- Специализация на шаблона
- C ++ Вариадични шаблони
- Заключение
- Препоръчително четене
Какво представляват шаблоните?
Както бе споменато по-горе, шаблоните са общи, т.е.независими от типа данни. Шаблоните се използват главно за осигуряване на многократна употреба и гъвкавост на програмите. Можем просто да създадем проста функция или клас, който приема тип данни като параметър и да приложим кода, който работи за всеки тип данни.
Например, ако искаме алгоритъмът за сортиране да работи за всички числови типове данни, както и символни низове, тогава просто ще напишем функция, която приема типа данни като аргумент и ще приложим техниката за сортиране.
След това в зависимост от типа данни (име на типа), който се предава на алгоритъма за сортиране, можем да сортираме данните независимо от типа на данните. По този начин не е необходимо да пишем десет алгоритми за десет типа данни.
По този начин шаблоните могат да се използват в приложения, при които изискваме кодът да бъде използваем за повече от един тип данни. Шаблоните се използват и в приложения, където повторната употреба на кода е от първостепенно значение.
Как да използвам шаблони / внедряване?
Шаблоните могат да бъдат внедрени по два начина:
- Като шаблон за функция
- Като шаблон на клас
Шаблон за функция
Шаблонът за функция е точно като нормална функция, но единствената разлика е, че докато нормалната функция може да работи само за един тип данни, а кодът на шаблон за функция може да работи за множество типове данни.
Въпреки че всъщност можем да претоварим нормална функция, за да работи с различни типове данни, шаблоните на функции винаги са по-полезни, тъй като трябва да напишем единствената програма и тя може да работи за всички типове данни.
След това ще видим изпълнението на шаблони за функции.
Общият синтаксис на шаблона на функцията е:
template T function_name(T args){ …… //function body }
Тук T е аргументът на шаблона, който приема различни типове данни, а класът е ключова дума. Вместо клас ключова дума можем да напишем и „typename“.
Когато даден тип данни се предаде на function_name, копието на тази функция се прави от компилатора с този тип данни като аргумент и функцията се изпълнява.
Нека да видим пример за по-добро разбиране на шаблоните за функции.
css интервю въпроси и отговори за опитни
#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. ключова дума за клас
Докато декларираме клас или функция на шаблон, ние използваме една от двете ключови думи клас или име на тип. Тези две думи са семантично еквивалентни и могат да се използват взаимозаменяемо.
Но в някои случаи не можем да използваме тези думи като еквивалентни. Например, когато използваме зависими типове данни в шаблони като “typedef”, използваме typename вместо class.
Също така ключовата дума 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 (първи).
С всяко извикване на сумиране списъкът с параметри се стеснява с един аргумент и в крайна сметка се постига основното условие. Резултатът показва сумирането за дълги цели числа и символи.
Заключение
С това завършваме този урок за шаблони в C ++. Шаблоните ни помагат да направим нашите програми общи, т.е.независими от типа.
Прочетете също = >> Урок за шаблон на колба
Общите програми винаги стоят на върха на останалите програми, тъй като не е необходимо да пишем отделни програми за всеки тип данни. По този начин разработването на генерични типово безопасни програми може да бъде важна стъпка към ефективното програмиране.
=> Проверете тук уроците за задълбочено обучение за C ++.
Препоръчително четене
- Урок за основната функция на Python с практически примери
- Как работи тестването, управлявано от данни (примери за QTP и селен)
- Многопоточност в C ++ с примери
- Урок за Python DateTime с примери
- Примерен шаблон за тестови случаи с примери за тестови случаи (Изтегляне)
- Изрежете командата в Unix с примери
- Примерен шаблон за доклад за изпитване за приемане с примери
- Синтаксис на командата Unix Cat, Опции с примери