Soluzione del 15 settembre 2015 Problema 1 Proposizione 1
Transcript
Soluzione del 15 settembre 2015 Problema 1 Proposizione 1
Soluzione del 15 settembre 2015 Problema 1 Proposizione 1: corretta; codicillo campione: int i = -1; const char * c = "ciao"; while(char cc = c[++i]) cout << cc; cout << endl; Proposizione 2: corretta; codicillo campione: template <class X> class Ciccio{}; template <> class Ciccio<int>{}; Proposizione 3: corretta; codicillo campione: template <class X> struct Ciccio { template <class Y> struct Pappo{}; }; int main() { Ciccio<int>::template Pappo<double> pappo; } Proposizione 4: errata; può trovarsi a destra di entrambi quando si voglia richiedere l’esecuzione di una funzione template membro di una classe, dall’interno di una funzione template, utilizzando rispettivamente, per accedervi, un oggetto o un puntatore a oggetto. Proposizione 5: errata; una funzione inserita nelle parentesi di decltype non viene mai eseguita. Proposizione 6: delle quattro conclusioni fornite quella corretta è evidentemente la seconda (valore = 64) perché l’operatore + ha precedenza sull’operatore <<. La prima e l’ultima conclusione sono solo folklore e purtroppo qualcuno è caduto sull’ultima. Proposizioni 7 e 8: entrambe errate nella loro apoditticità, perché è pur vero che “in generale” in C++ la proprietà commutativa non vale, ma, appunto, in generale, dato che esistono quanti si vogliano controesempi in cui la commutatività è palese; quanto all’associatività è pur vero che esistono chiare regole di associatività per ogni operatore, ma esse non pongono in atto né sempre né mai la proprietà associativa algebrica. Proposizione 9: errata perché ad un try possono essere posposti altrettanti catch quanti sono i tipi che il buon programmatore può definire, ossia, teoricamente, infiniti. Proposizione 10: errata, perché ogni catch “fa ambito” per suo conto e quindi il nome attribuito alla variabile catturata non importa un fico secco. Problema 2 Ecco un possibile header file in cui è definita una versione del manipolatore richiesto: # # # # # ifndef MANIPOLATORE COL INCLUSO define MANIPOLATORE COL INCLUSO define NERO ’0’ define ROSSO ’1’ define VERDE ’2’ # # # # # # define define define define define define GIALLO ’3’ BLU ’4’ MAGENTA ’5’ CIANO ’6’ BIANCO ’7’ AUTO 0 # include <iostream> using namespace std; class Piffero { static int stato; char s[6]{27, ’[’, ’3’, ’?’, ’m’, 0}; const char * r = "\033[0m"; friend ostream & operator << (ostream&, Piffero); public: Piffero(char c) {s[3] = c;} }; ostream & operator << (ostream&o, Piffero p) { if(o != cout && o != clog && o != cerr) return o; bool scrivi(true); if(!p.s[3]) { if(p.stato) o << p.r; if(o == cerr) p.s[3] = ROSSO; else if(o == clog) p.s[3] = GIALLO; else scrivi = false;} p.stato = p.s[3]; if(scrivi) return o << p.s; return o;} Piffero col(char c) { return Piffero(c);} int Piffero::stato = 0; # endif Il precedente documento, se nomato manipolatore colorante, fa funzionare perfettamente la seguente main di test: # include <manipolatore colorante> # include <fstream> int main() { ofstream os("pappone"); os << col(VERDE) << "questo finisce normalmente nel file pappone\n"; os.close(); cout << col(CIANO) << "questo si scrive in ciano\n"; cerr << col(AUTO) << "questo si scrive in rosso\n"; cout << col(AUTO) << "questo si scrive normale\n"; clog << col(AUTO) << "questo si scrive in giallo\n"; cout << col(BIANCO) << "questo si scrive in bianco\n"; cout << col(AUTO); }