Da circa un paio d’anni l’interesse per il C++ è aumentato notevolmente. Che sia per la rivoluzione portata dal nuovo standard (C++11) o per necessità industriali, – legate, ad esempio, a scalabilità e performance – è indubbio che il linguaggio sia profondamente radicato in sistemi che usiamo quotidianamente. Ad esempio MySQL, Oracle, ma anche Office, Photoshop e Facebook. E questo link ne raccoglie molti altri.
Il nuovo standard ha cambiato notevolmente il linguaggio, non solo per aver aggiunto elementi inediti alla libreria, ma anche – e soprattutto – per averne mutato lo stile e gli idiomi più classici. Pensiamo, ad esempio, al tornare un oggetto da una funzione. Nel C++98 non è insolito utilizzare uno stile C-like per evitare di ritornare per oggetti per valore. Questo – a meno di ottimizzazioni del compilatore, come il Return-Value Optimization (RVO) – è per tenersi lontano da copie potenzialmente costose. Ora, grazie all’introduzione della move semantics, funzioni di questo genere:
void Calculate(vector<HugeType>& result)
{
// ... fill result
}
possono essere trasformate in:
vector<HugeType> Calculate()
{
vector<HugeType> result;
// ... fill result
return result;
}
senza incorrere in inutili copie. Questo è garantito dallo standard, senza doversi affidare alle opzioni del compilatore. Più in generale, il C++11 consente di operare con una sintassi chiara su oggetti temporanei o, più in generale, su RVALUE.
Ma il C++11 aggiunge anche diverse facilitazioni per migliorare produttività e sintesi. Come auto, per dedurre automaticamente il tipo di una variabile:
map<string, vector<int>> aMap;
// C++98
map<string, vector<int>>::iterator it = aMap.begin();
// C++11
auto it = aMap.begin();
Oppure il range-based for loop per iterare su un range con una sintassi compatta:
// C++98
for (vector<int>::iterator i = v.begin(); i != v.end(); ++i)
{
cout << *i << " ";
}
// C++11
for (auto i : v)
{
cout << i << " ";
}
Le lambda expressions facilitano e rendono naturale l’utilizzo degli algoritmi e dello stile funzionale:
all_of( begin(vec), end(vec), [](int i){ return (i%2)==0; } );
Le initializer_list estendono la classica inizializzazione con parentesi graffe delle struct, per essere usata in modo personalizzato:
class MyVector
{
public:
MyVector(std::initializer_list<int> list);
...
};
...
MyVector vec = {1,2,3,4,5};
Correlato alle initializer_list, anche il fastidioso problema del most vexing parse è stato risolto, con la uniform initialization. Il C++11 consente di inizializzare qualsiasi oggetto con una sintassi omogenea:
struct BasicStruct
{
int x;
double y;
};
struct AltStruct
{
AltStruct(int x, double y) : x_{x}, y_{y} {}
private:
int x_;
double y_;
};
BasicStruct var1{5, 3.2};
AltStruct var2{2, 4.3};
Proseguendo questa panoramica molto generale, è importante ricordare che anche la libreria standard ha accolto tante novità. A partire dagli smart pointers, deprecando il frainteso auto_ptr:
// C++98
int* anIntPtr = new int(10);
...
delete anIntPtr;
// C++11
unique_ptr<int> anIntPtr( new int(10) ); // will be deleted
Passando poi per nuove strutture dati, come gli unordered container, le tuple, le forward_list, … Anche il supporto alla metaprogrammazione è cresciuto, con l’introduzione di diversi type_traits standard e decltype per inferire il tipo di un’espressione.
E finalmente è possibile scrivere codice multi-thread portabile, sfruttando la libreria nativa:
thread aThread( some_function ); // may be a lambda or any callable obj
thread anotherThread ( another_function );
aThread.join();
anotherThread.join();
Questa panoramica è solo una piccoa parte di tutta la storia. Per tutte le novità del C++11 potete consultare, ad esempio, la pagina relativa su wikipedia.
Non tutto è però gratuito. Per sfruttare al massimo tutte le innovazioni del C++11 (e tra breve del C++14) è necessario comprenderle ed applicarle con disciplina. Non è difficile trovare siti, articoli, tutorial e molto altro su tantissimi aspetti del nuovo standard. Spesso tutto questo volume di informazioni mette in difficoltà chi desidera apprendere gradualmente e non sa da dove iniziare. La prossima sezione raccoglie in modo ordinato alcune delle risorse più importanti ad apprendere e restare aggiornati.
Inoltre, il motivo di questa categoria – DOs & DON’Ts – è proprio quello di suggerire al lettore alcune nuove pratiche e idiomi, rimpiazzando il vecchio stile.
C++ Revolution: come inziare
Il C++11 ha mosso molti programmatori C++ verso la riscoperta e la rivisitazione del linguaggio; alcuni si sono ritirati perché convinti in un aumento di complessità, mentre altri ne hanno tratto diversi benefici. Negli ultimi anni sono proliferate risorse, articoli, video e materiale divulgativo per apprendere e approfondire molti aspetti del nuovo standard. Questa breve sezione conclusiva vuole raccogliere in modo ordinato risorse utili per approfondire e restare aggiornati, specialmente per chi è ancora indeciso e smarrito.
Consulta isocpp.org periodicamente
Il riferimento ufficiale dello standard – da circa novembre 2012 – è isocpp.org. Si tratta dell’unico catalizzatore ufficiale di risorse e news. Consultare periodicamente questo sito consente di restare aggiornati su eventi, libri, video, articoli e molto altro.
Considera alcuni testi fondamentali
I testi che sento di raccomandare a chi vuole conoscere in modo approfondito le novità del C++11 sono i seguenti:
- The C++ Programming Language (4th edition), di Bjarne Stroustrup (la bibbia, aggiornata al C++11)
- Overview of the New C++, di Scott Meyers (sono slides dense di contenuti),
- The C++ Standard Library (2nd edition), di Nicolai Josuttis (attualmente la reference più completa sulla libreria standard, aggiornata al C++11),
- C++ Concurrency in Action, di Anthony Williams (a proposito di multithreading in C++11).
Guarda i video delle ultime conferenze
Se desiderate guardare qualche video, consiglierei:
- Le lezioni di Stephen T. Lavavej (esistono anche lezioni sulla standard library, basic & advanced),
- GoingNative2012 (un’importante conferenza by Microsoft),
- C++ And Beyond 2012 (conferenza di Meyers/Sutter/Alexandrescu)
Prova diversi compilatori
Un altro suggerimento è di provare il proprio codice su diversi compilatori, perché non tutti sono 100% compliant col C++11 (ad oggi solo GCC). Grazie ad alcuni compilatori online è possibile compilare ed eseguire direttamente dal browser.
Consulta la categoria DOs & DON’Ts!
Come annunciato, l’obiettivo della nostra categoria DOs & DON’Ts è quello di suggerire nuovi idiomi e pratiche stilistiche, rimpiazzando il vecchio modo di programmare in C++, ove possibile. Preferiamo la sinteticità del codice. Non mancheranno, quindi, snippet con confronti “ieri/oggi” e link a codice da compilare e provare direttamente online. Speriamo, poi, di poter discutere con i lettori non solo nei commenti ma anche (e soprattutto) nei vari gruppi di discussione.
Chiaramente, invitiamo chiunque voglia contribuire a farlo!
Meraviglioso, mi ero interessato l’anno scorso del nuovo standard e ho anche scritto dei tutorial, poi mi sono dovuto allontanare per motivi accademici.
Vedo che sono andati ancora avanti!
Se volete dare un occhiata sono qui http://www.thedarshan.com/informatica/il-c-non-e-ancora-morto/
quando finisco con la laurea voglio rimettermi al passo completamente.
Grazie Vincenzo! Bel lavoro quei tutorial 🙂
Anche noi stiamo scrivendo un po’ di articoli sulle nuove buone pratiche di programmazione in C++.
Se ti va di contribuire:
http://www.italiancpp.org/articoli/diventa-un-autore/
Marco