Zaawansowane CPP/Ćwiczenia 9: Szablony wyrażeń: Różnice pomiędzy wersjami
Nie podano opisu zmian |
Nie podano opisu zmian |
||
(Nie pokazano 56 wersji utworzonych przez 4 użytkowników) | |||
Linia 1: | Linia 1: | ||
{{cwiczenie|1|| | |||
Zaimplementuj szablony funkcji <tt>table1</tt>, <tt>table2</tt> i <tt>table3</tt>, generujące tabele | |||
prawdy dla jednej, dwu lub trzech zmiennych logicznych. Argumentem tych funkcji ma być funkcja przyjmująca, w zależności od funkcji, od 1 do 3 argumentów typu <tt>bool</tt>, np.: | |||
<nowiki> bool And(bool q,bool r) {return q && r;} | |||
table2(And) ;</nowiki> | |||
powinno wygenerować : | powinno wygenerować : | ||
<nowiki>------------- | <nowiki>-------------- | ||
| 0 | 0 || 0 | | | 0 | 0 || 0 | | ||
| 0 | 1 || 0 | | | 0 | 1 || 0 | | ||
| 1 | 0 || 0 | | | 1 | 0 || 0 | | ||
| 1 | 1 || 1 | | | 1 | 1 || 1 | | ||
-------------</nowiki> | --------------</nowiki> | ||
Podobnie dla <tt>table1</tt> i <tt>table3</tt>. | |||
}} | |||
<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"> | |||
Patrz plik [[media:Table.h | table.h]]. | |||
</div></div> | |||
{{cwiczenie|2|| | |||
Zaimplementuj operatory <code><nowiki>&&</nowiki></code>(i), <code><nowiki>||</nowiki></code>(lub), <code><nowiki>!</nowiki></code>(zaprzeczenie), | Napisz szablony wyrażeń, które będzie można użyć | ||
<code><nowiki>>></nowiki></code> (implikacja) i <code><nowiki>==</nowiki></code>(równoważność). | z powyższymi szablonami. Zaimplementuj trzy klasy <tt>First</tt>, <tt>Second</tt> i <tt>Third</tt>, oznaczające odpowiednio pierwszy, drugi i trzeci argument funkcji logicznej. Zaimplementuj operatory <code><nowiki>&&</nowiki></code>(i), <code><nowiki>||</nowiki></code>(lub), <code><nowiki>!</nowiki></code>(zaprzeczenie), | ||
<code><nowiki>>></nowiki></code> (implikacja) i <code><nowiki>==</nowiki></code>(równoważność) oraz możliwość korzystania ze stałych logicznych <tt>True</tt> i <tt>False</tt>. Np.: | |||
First q; | |||
Second r; | |||
table2(q >> r); | |||
powinno wygenerować: | |||
<nowiki>------------- | <nowiki>-------------- | ||
| 0 | 0 || 1 | | | 0 | 0 || 1 | | ||
| 0 | 1 || 1 | | | 0 | 1 || 1 | | ||
| 1 | 0 || 0 | | | 1 | 0 || 0 | | ||
| 1 | 1 || 1 | | | 1 | 1 || 1 | | ||
-------------</nowiki> | --------------</nowiki> | ||
a | |||
table1(True <nowiki>==</nowiki> q); | |||
powinno wygenerować: | |||
<nowiki>--------- | |||
| 0 | 0 | | |||
| 1 | 1 | | |||
---------</nowiki> | |||
}} | |||
<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"> | |||
Rozwiązanie jest całkowicie analogiczne do szblonów wyrażeń podanych na wykładzie. Zaczynamy od klas reprezentujących odpowiednio pierwszy, drugi i trzeci argument wyrażenia logicznego: | |||
struct First { | |||
bool operator()(bool q) {return q;}; | |||
bool operator()(bool q, bool r) {return q;}; | |||
bool operator()(bool q, bool r, bool t) {return q;}; | |||
}; | |||
struct Second { | |||
bool operator()(bool q, bool r) {return r;}; | |||
bool operator()(bool q, bool r, bool t) {return r;}; | |||
}; | |||
struct Third { | |||
bool operator()(bool q, bool r, bool t) {return t;}; | |||
}; | |||
Następnie definiujemy klasę stałych logicznych: | |||
class Constant { | |||
bool _val; | |||
public | |||
Constant(bool q):_val(q) {}; | |||
bool operator()(bool q) {return _val;}; | |||
bool operator()(bool q, bool r) {return _val;}; | |||
bool operator()(bool q, bool r, bool s) {return _val;}; | |||
}; | |||
i dwie globalne stałe: | |||
namespace Logic { | |||
Constant True(true); | |||
Constant False(false); | |||
} | |||
Używamy przestrzeni nazw Logic aby zmniejszyć ryzyko konfliktu nazw. | |||
Klasa <tt>And</tt> reprezentuje koniunkcję dwu wyrażeń logicznych: | |||
template<typename L,typename R> class And { | |||
L _lhs; | |||
R _rhs; | |||
public: | |||
And(L l,R r):_lhs(l),_rhs(r) {}; | |||
bool operator()(bool q) {return _lhs(q) && _rhs(q);} | |||
bool operator()(bool q, bool r) {return _lhs(q,r) && _rhs(q,r);} | |||
bool operator()(bool q, bool r, bool s) {return _lhs(q,r,s) && _rhs(q,r,s);} | |||
}; | |||
Obiekty tej klasy są generowane przez operator: | |||
template<typename L,typename R> And<L,R> operator&&(L l,R r) | |||
{return And<L,R>(l,r);} | |||
Jeśli będziemy korzystać tylko z naszych stałych logicznych <tt>Logic::True</tt> i <tt>Logic::False</tt>, to niepotrzebne są dodatkowe przeciążenia operatora. | |||
Pozostałe operatory implementujemy analogicznie. Całość kodu jest podana w pliku [[media:Logic.h | logic.h]]. | |||
</div></div> | |||
{{cwiczenie|3|| | |||
Zaimplementuj szablon funkcji, który będzie przyjmował jako jeden z parametrów szablonu ilość zmiennych logicznych i będzie łączył działanie funkcji <tt>table1</tt>, <tt>table2</tt> i <tt>table3</tt>. Np.: | |||
table<2>(And); | |||
powinno być równoważne wywołaniu: | |||
table2(And); | |||
}} | |||
<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"> | |||
Wykorzystaj pomocniczy szablon klasy aby móc skorzystać ze specjalizacji częściowej. | |||
</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"> | |||
Patrz plik [[media:Table.h | table.h]]. | |||
</div></div> |
Aktualna wersja na dzień 19:43, 4 paź 2006
Ćwiczenie 1
Zaimplementuj szablony funkcji table1, table2 i table3, generujące tabele prawdy dla jednej, dwu lub trzech zmiennych logicznych. Argumentem tych funkcji ma być funkcja przyjmująca, w zależności od funkcji, od 1 do 3 argumentów typu bool, np.:
bool And(bool q,bool r) {return q && r;} table2(And) ;
powinno wygenerować :
-------------- | 0 | 0 || 0 | | 0 | 1 || 0 | | 1 | 0 || 0 | | 1 | 1 || 1 | --------------
Podobnie dla table1 i table3.
Ćwiczenie 2
Napisz szablony wyrażeń, które będzie można użyć
z powyższymi szablonami. Zaimplementuj trzy klasy First, Second i Third, oznaczające odpowiednio pierwszy, drugi i trzeci argument funkcji logicznej. Zaimplementuj operatory &&
(i), ||
(lub), !
(zaprzeczenie),
>>
(implikacja) i ==
(równoważność) oraz możliwość korzystania ze stałych logicznych True i False. Np.:
First q; Second r; table2(q >> r);
powinno wygenerować:
-------------- | 0 | 0 || 1 | | 0 | 1 || 1 | | 1 | 0 || 0 | | 1 | 1 || 1 | --------------
a
table1(True == q);
powinno wygenerować:
--------- | 0 | 0 | | 1 | 1 | ---------
Ćwiczenie 3
Zaimplementuj szablon funkcji, który będzie przyjmował jako jeden z parametrów szablonu ilość zmiennych logicznych i będzie łączył działanie funkcji table1, table2 i table3. Np.:
table<2>(And);
powinno być równoważne wywołaniu:
table2(And);