Zaawansowane CPP/Ćwiczenia 8: Metaprogramowanie: Różnice pomiędzy wersjami
Nie podano opisu zmian |
Nie podano opisu zmian |
||
Linia 145: | Linia 145: | ||
<div class="mw-collapsible mw-made=collapsible mw-collapsed"><span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Podpowiedź</span><div class="mw-collapsible-content" style="display:none"> | <div class="mw-collapsible mw-made=collapsible mw-collapsed"><span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Podpowiedź</span><div class="mw-collapsible-content" style="display:none"> | ||
Konieczne będzie użycie specjalizacji częściowej. W tym celu użyj pomocniczej klasy (specjalizacja częściowa jest niedozwolona dla funkcji). | Konieczne będzie użycie specjalizacji częściowej. W tym celu użyj pomocniczej klasy (specjalizacja częściowa jest niedozwolona dla funkcji). | ||
</div></div> | |||
<div class="mw-collapsible mw-made=collapsible mw-collapsed"><span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiązanie</span><div class="mw-collapsible-content" style="display:none"> | |||
Ponieważ warunek brzegowy <math>N</math>=1 będzie wymagał specjalizacji częściowej, implementujemy iloczyn skalarny jako składową klasy: | |||
template<size_t N,typename T = double > struct Inner { | |||
static T dot(T *a,T *b) { | |||
return (*a)*(*b)+Inner<N-1,T>::dot(++a,++b); | |||
} | |||
}<br> | |||
template<typename T > struct Inner<1,T> { | |||
static T dot(T *a,T *b) { | |||
return (*a)*(*b); | |||
} | |||
}; | |||
a następnie dodajemy funkcję wywołującą tę metodę: | |||
template<size_t N,typename T> T dot( T *a,T *b) { | |||
return Inner<N,T>::dot(a,b); | |||
}; | |||
Patrz plik [http://osilek.mimuw.edu.pl/images/8/8b/Inner.h inner.h]. | |||
</div></div> | </div></div> | ||
Linia 163: | Linia 186: | ||
elementowi <math>\displaystyle A_{i,j}</math> odpowiada <math>A[M*i+j]</math>. | elementowi <math>\displaystyle A_{i,j}</math> odpowiada <math>A[M*i+j]</math>. | ||
}} | }} | ||
<div class="mw-collapsible mw-made=collapsible mw-collapsed"><span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiązanie</span><div class="mw-collapsible-content" style="display:none"> | |||
Najpierw definiujemy szablon implementujemy iloczyn skalarny jako składową klasy: | |||
template<size_t N,typename T = double > struct Inner { | |||
static T dot(T *a,T *b) { | |||
return (*a)*(*b)+Inner<N-1,T>::dot(++a,++b); | |||
} | |||
}<br> | |||
template<typename T > struct Inner<1,T> { | |||
static T dot(T *a,T *b) { | |||
return (*a)*(*b); | |||
} | |||
}; | |||
a następnie dodajemy funkcję wywołującą tę metodę: | |||
template<size_t N,typename T> T dot( T *a,T *b) { | |||
return Inner<N,T>::dot(a,b); | |||
}; | |||
Patrz plik [http://osilek.mimuw.edu.pl/images/8/8b/Inner.h inner.h]. | |||
</div></div> |
Wersja z 11:43, 21 wrz 2006
Ćwiczenie 1
Napisz szablon funkcji lub klasy wyliczający funkcję silnia:
Ćwiczenie 2
Zaimplementuj szablon Pow<N,M>
obliczający
. Np.:
Pow<3,4>::val;
powinno mieć wartość 81.
Ćwiczenie 3
Wymyśl i zaimplementuj jako metaprogram szybszy algorytm funkcji pow(x)
.
Ćwiczenie 4
Napisz szablon generujący pierwsze wyrazów rozwinięcia funkcji :
Możesz skorzystać z rozwiązań wcześniejszych zadań.
Ćwiczenie 5
Napisz szablon generujący funkcję implementującą iloczyn skalarny dwu wektorów.
template<size_t N> double inner(double *x, double *y);
Parametrem szablonu ma być dlugość mnożonych wektorów.
Ćwiczenie 6
Rozszerz powyższy szablon tak, aby również typ elementów wektora był parametrem szablonu:
template<size_t N, typename T> T dot(T *x, T *y);
Ćwiczenie 7
Napisz szablon generujący funkcję implementującą iloczyn macierzy i wektora o elementach:
void matrix_v<N>(double *A,double *v,double *u)
Tablica jest reprezentowana w pamięci zgodnie z konwencją , tzn. wiersz po wierszu: elementowi odpowiada .