Шаблон метапрограмирањаШаблон метапрограмирања (ТМП) је техника метапрограмирања у којој шаблоне користи компајлер за генерисање привременог изворног кода, који је припојен компајлеру са остатком изворног кода, а затим састављен. Излаз ових шаблона укључује компилирања константе, структуре података и комплетне функције. Коришћење шаблона може се посматрати као извршење компилирања. Техника се користи од стране бројних језика, најпознатији су C++, али такође Curl, D, и XL. Шаблон метапрограмирања је, у извесном смислу, откривен случајно. Неки други језици подржавају сличан, ако не и више моћно компилирање објеката (као што је Lisp), али они су ван обима овог члана. Компоненте шаблона метапрограмирањаКоришћење шаблона као техника метапрограмирања захтева две одвојене операције: шаблон мора бити дефинисан, а дефинисан шаблон мора бити инстанциран. Дефиниција шаблона описује општи облик генерисаног изворног кода, а инстанцирање изазива посебан сет изворног кода који се генерише из генеричког облика у шаблон. Шаблон метапрограмирања је Тјурингова потпуност, што значи да свако експресно израчунавање рачунарски програм може да израчуна, у неком облику, од стране шаблона метапрограма.[1] Шаблони се разликују од макроа. Макро, што је такође одлика компилирања језика, генерише код у-линији користећи манипулацију текста и замену. Макро системи често имају ограничене способности компилирања процеса протока и обично немају свест о семантици и типу система њиховог пратиоца језика (изузетак треба да буду Lisp макрои, који су написани у самом Lisp-у и укључују манипулацију и замену Lisp кода представљен као структура података насупрот тексту). Шаблони метапрограмирања немају променљиве варијабле- да се, без променљиве може променити вредност након што је иницијализована, стога шаблон метапрограмирања може се посматрати као облик функционалног програмирања. У ствари, многи шаблони имплементације спроводе контролу протока само кроз рекурзије, као што се види на примеру. Коришћење шаблона метапрограмирањаИако се синтакса шаблона метапрограмирања обично веома разликује од програмског језика са којим се користи, има практичне користи. Неки уобичајени разлози да користе шаблоне су да спроведу генеричко програмирање (избегавајући делове кода који су слични, осим неких мањих варијација) или да врши аутоматску оптимизацију компилирања као што раде нешто једном у компајлирању а не сваки пут да се програм води - на пример, тако што компајлер одмотава петље да елиминише скокове и тачке петље декрементира кад год се извршава програм. Компилирање класа генерацијаШта тачно "програмирање компилирањем" значи може се илустровати са примером факторијел функција, која у шабонлу C ++ може бити писана коришћењем рекурзије на следећи начин: unsigned int factorial(unsigned int n) {
return n == 0 ? 1 : n * factorial(n - 1);
}
// Примери коришћења:
// факторијал(0) би дало 1;
// факторијал(0) би дало 24.
Код изнад ће спровести у време извршавања за утврђивање факторијалне вредност литерала 4 и 0. Помоћу шаблона метапрограмирања и шаблона специјализације да обезбеди завршни услов за рекурзије, у факторијалима који се користе у програму-игнорише оне факторијале који се не користе -могу се израчунати компајлирањем овим кодом: template <unsigned int n>
struct factorial {
enum { value = n * factorial<n - 1>::value };
};
template <>
struct factorial<0> {
enum { value = 1 };
};
// Примери коришћења:
// факторијал<0> :: вредност би дало 1;
// факторијал<0> :: вредност би дало 24.
Код изнад израчунава факторску вредност литерала 4 и 0 у компајлирању и користи резултат као да су пре новосрачунате константе. Да бисте могли да користите шаблоне на овај начин, преводилац мора знати вредност својих параметара у компајлирању, који има природни предуслов да факторијална <X> :: вредност може се користити само ако је X познат у време компилације. Другим речима, X мора бити константна дословно или константан израз. У C++11, constexpr, начин да се дозволи преводиоцу да изврши једноставне изразе сталне, додаје се. Користећи constexpr, могу се користити уобичајене рекурзивне факторске дефиниције.[2] Оптимизација компилирања кодаФакторијал пример изнад је један од примера компилирања оптимизације кода да су сви факторијалии коришћени од стране програма унапред састављен и убризгава као нумеричке константе на компилацији, штеди како Рун-тиме преко главе и меморије отиска. То је, међутим, релативно минорна оптимизација. Као друго, још важније, пример компилирања одмотавања петље, шаблон метапрограмирања се може користити за стварање дужина-н векторских часова (где је н познато на компајлирање). Корист током традиционалне дужине н вектора је да се петље могу одмотати, што доводи до веома оптимизираног кода. Као пример, размотримо оператера додатака. Дужине-Н вектора додатак може бити написан као template <int length>
Vector<length>& Vector<length>::operator+=(const Vector<length>& rhs)
{
for (int i = 0; i < length; ++i)
value[i] += rhs.value[i];
return *this;
}
Када преводилац инстанцира предложак функције ако што је дефинисано горе, следећи код могже бити произведен: template <>
Vector<2>& Vector<2>::operator+=(const Vector<2>& rhs)
{
value[0] += rhs.value[0];
value[1] += rhs.value[1];
return *this;
}
Оптимизер компајлер треба да буде у стању да развијте Међутим, узети опрез јер то може изазвати надимање кода, као посебан одвијени код ће се генерисати за сваки 'N' (вектор величине) можете инстанцирати. Статички полиморфизамПолиморфизам је заједнички стандард програмирања објеката где се изведени објекти могу користити као примери њиховог основног објекта, али где ће бити покренуте методе изведеног објеката, као у овом коду class Base
{
public:
virtual void method() { std::cout << "Base"; }
virtual ~Base() {}
};
class Derived : public Base
{
public:
virtual void method() { std::cout << "Derived"; }
};
int main()
{
Base *pBase = new Derived;
pBase->method(); // излаз "Derived"
delete pBase;
return 0;
}
где ће сва позивања на template <class Derived>
struct base
{
void interface()
{
// ...
static_cast<Derived*>(this)->implementation();
// ...
}
};
struct derived : base<derived>
{
void implementation()
{
// ...
}
};
Овде основна класа шаблона ће искористити чињеницу да функције као чланови органиа нису инстанциране, тек после њихове изјаве, и то ће користити чланови изведене класе у оквиру својих функција чланица, преко употребе Још једна слична употреба је "Бартон Накмен трик", понекад називају "ограничен шаблон проширења", где заједничка функционалност може бити постављена у основне класе која се не користи као уговор већ као неопходна компонента да се спроведе усклађеност понашања, док минимизира лод редундантност. Предности и недостаци шаблона метапрограмирања
Види још
Референце
Литература
Додатна литература
Спољашње везе
|
Portal di Ensiklopedia Dunia