Ця стаття не містить . (грудень 2019) |
Ця стаття містить текст, що не відповідає . |
В програмуванні, варіативний шаблон — зі змінною кількістю аргументів.
Варіативні шаблони підтримуються мовою (починаючи з стандарту ), та мовою програмування D.
Синтаксис варіативного шаблону в мові C++11 в загальному випадку наступний:
template<typename... Values> class tuple; // нуль або більше аргументів
Якщо потрібно заборонити використання шаблону без параметрів, то використовують наступний підхід, що вимагає використання як мінімум одного параметра:
template<typename First, typename... Rest> class tuple; // один або більше аргументів
Варіативні шаблони також можуть застосовуватися з функціями:
template<typename... Params> void printf(const std::string &str_format, Params... parameters);
Часто використовують рекурсивний виклик варіативних шаблонів. Самі варіаційні параметри не є доступними для реалізації функції або класу. Тому для реалізації заміни звичного printf через варіативний шаблон у C++11 типовим підходом буде такий:
// базовий варіант void printf(const char *s) { while (*s) { if (*s == '%') { if (*(s + 1) == '%') { ++s; } else { throw std::runtime_error("неправильний формат рядка: відсутні аргументи"); } } std::cout << *s++; } } // рекурсивний template<typename T, typename... Args> void printf(const char *s, T value, Args... args) { while (*s) { if (*s == '%') { if (*(s + 1) == '%') { ++s; } else { std::cout << value; s += 2; // зрозуміло, що це працюватиме лише з 2-х символьними специфікаторами ( %d, %f, і т.п. ); але не з %5.4f і т.п. printf(s, args...); // буде викликатися навіть для *s рівного nullptr, але не робитиме нічого, просто ігноруватиме аргументи return; } } std::cout << *s++; } }
Зауважте, що побудована з застосуванням варіативного шаблону версія printf викликає себе рекурсивно або (коли список аргументів args… буде порожній) викликає базовий варіант.
Приклад
Приклад короткої програми на мові С++ де застосовано варіативний шаблон, що підраховує суму змінного числа аргументів:
#include <iostream> template<typename T> T SUM(T v) { return v; } template<typename T, typename T1, typename... Ts> T SUM(T v, T1 v1, Ts... vs) { return v + SUM(v1, vs...); } int main(int argc, char**) { std::cout << SUM(2, 2) << std::endl; std::cout << SUM(argc, 1, 2, 3) << std::endl; }
Вирази згортання і варіативні шаблони
У стандарті C++17 з'явились вирази згортання (англ. fold expressions), що значно полегшують використання технології варіативних шаблонів. Наприклад, з їх використанням код функції SUM може мати такий вигляд:
template<typename ...Ts> //C++17
//Універсальні посилання на кожен з параметрів
auto SUM(Ts&& ... param){
return (std::forward<Ts>(param) + ... + 0); //Приймає вигляд (param1 + (param2 + (...(0)))
//Зверніть увагу: 0 виступає в ролі нейтрального значення
}
Розглянемо можливий виклик функції:
int main(int argc, char *argv[])
{
constexpr int a = 100;
std::cout<<SUM(10, 20, a); //Результат: 130
}
Див. також
Вікіпедія, Українська, Україна, книга, книги, бібліотека, стаття, читати, завантажити, безкоштовно, безкоштовно завантажити, mp3, відео, mp4, 3gp, jpg, jpeg, gif, png, малюнок, музика, пісня, фільм, книга, гра, ігри, мобільний, телефон, android, ios, apple, мобільний телефон, samsung, iphone, xiomi, xiaomi, redmi, honor, oppo, nokia, sonya, mi, ПК, web, Інтернет
Cya stattya ne mistit posilan na dzherela Vi mozhete dopomogti polipshiti cyu stattyu dodavshi posilannya na nadijni avtoritetni dzherela Material bez dzherel mozhe buti piddano sumnivu ta vilucheno gruden 2019 Cya stattya mistit tekst sho ne vidpovidaye enciklopedichnomu stilyu Bud laska dopomozhit udoskonaliti cyu stattyu pogodivshi stil vikladu zi stilistichnimi pravilami Vikipediyi Mozhlivo storinka obgovorennya mistit zauvazhennya shodo potribnih zmin V programuvanni variativnij shablon shablon zi zminnoyu kilkistyu argumentiv Variativni shabloni pidtrimuyutsya movoyu C pochinayuchi z standartu C 11 ta movoyu programuvannya D Sintaksis variativnogo shablonu v movi C 11 v zagalnomu vipadku nastupnij template lt typename Values gt class tuple nul abo bilshe argumentiv Yaksho potribno zaboroniti vikoristannya shablonu bez parametriv to vikoristovuyut nastupnij pidhid sho vimagaye vikoristannya yak minimum odnogo parametra template lt typename First typename Rest gt class tuple odin abo bilshe argumentiv Variativni shabloni takozh mozhut zastosovuvatisya z funkciyami template lt typename Params gt void printf const std string amp str format Params parameters Chasto vikoristovuyut rekursivnij viklik variativnih shabloniv Sami variacijni parametri ne ye dostupnimi dlya realizaciyi funkciyi abo klasu Tomu dlya realizaciyi zamini zvichnogo printf cherez variativnij shablon u C 11 tipovim pidhodom bude takij bazovij variant void printf const char s while s if s if s 1 s else throw std runtime error nepravilnij format ryadka vidsutni argumenti std cout lt lt s rekursivnij template lt typename T typename Args gt void printf const char s T value Args args while s if s if s 1 s else std cout lt lt value s 2 zrozumilo sho ce pracyuvatime lishe z 2 h simvolnimi specifikatorami d f i t p ale ne z 5 4f i t p printf s args bude viklikatisya navit dlya s rivnogo nullptr ale ne robitime nichogo prosto ignoruvatime argumenti return std cout lt lt s Zauvazhte sho pobudovana z zastosuvannyam variativnogo shablonu versiya printf viklikaye sebe rekursivno abo koli spisok argumentiv args bude porozhnij viklikaye bazovij variant PrikladPriklad korotkoyi programi na movi S de zastosovano variativnij shablon sho pidrahovuye sumu zminnogo chisla argumentiv include lt iostream gt template lt typename T gt T SUM T v return v template lt typename T typename T1 typename Ts gt T SUM T v T1 v1 Ts vs return v SUM v1 vs int main int argc char std cout lt lt SUM 2 2 lt lt std endl std cout lt lt SUM argc 1 2 3 lt lt std endl Virazi zgortannya i variativni shabloniU standarti C 17 z yavilis virazi zgortannya angl fold expressions sho znachno polegshuyut vikoristannya tehnologiyi variativnih shabloniv Napriklad z yih vikoristannyam kod funkciyi SUM mozhe mati takij viglyad template lt typename Ts gt C 17 Universalni posilannya na kozhen z parametriv auto SUM Ts amp amp param return std forward lt Ts gt param 0 Prijmaye viglyad param1 param2 0 Zvernit uvagu 0 vistupaye v roli b nejtralnogo znachennya b Rozglyanemo mozhlivij viklik funkciyi int main int argc char argv constexpr int a 100 std cout lt lt SUM 10 20 a Rezultat 130 Div takozhVariativna funkciya Variativnij makros