# C++11

Il C++11, conosciuto precedentemente come C++0x, è uno standard per il linguaggio di programmazione C++ che ha sostituito la revisione del 2003 (C++03). Questo standard comprende numerose novità per il core del linguaggio ed estende la libreria standard incorporando molte delle librerie del cosiddetto TR1 (il “C++ Standards Committee's Library Technical Report”).
Il “C++ Standards Committee” ha completato il nuovo standard nel settembre 2008 e la bozza è stata presentata con il nome di N3126 il 21 agosto 2010. Il 25 marzo 2011 l'ISO ha votato la bozza finale (targata N3290) che è stata contrassegnata come FDIS (Final Draft International Standard). Il 1º settembre 2011 è stata pubblicata la versione finale del C++11 da parte di ISO e IEC (ISO/IEC 14882:2011(E) Programming Languages—C++, Third Edition.) Molte software house e progetti open source stanno sviluppando vari compilatori già funzionanti.
Una delle ragioni che spingono ad un processo evolutivo un linguaggio di programmazione come il C++ è la necessità di poter programmare più velocemente, elegantemente e, soprattutto, ottenendo un codice la cui manutenzione sia agevole. Questo processo porta inevitabilmente verso l'incompatibilità con il vecchio codice, per questo motivo, durante il processo di sviluppo del C++, ogni tanto si sono presentate alcune incompatibilità con le versioni precedenti. Secondo quanto annunciato da Bjarne Stroustrup (inventore del linguaggio C++, nonché membro del comitato), questo standard ha mantenuto pressoché al 100% la compatibilità con lo standard precedente.
I maggiori benefici non arrivano da soluzioni che permetteranno di scrivere meglio una linea individuale di codice, ma da quelle soluzioni che consentono al programmatore di risolvere un problema ed organizzare meglio il codice; così come avvenuto con l'introduzione della programmazione orientata agli oggetti ed alla programmazione generica (i template).

## Le modifiche annunciate per l'imminente aggiornamento dello standard

Come detto le modifiche allo standard C++ riguarderanno sia il linguaggio di programmazione e sia la libreria standard.
Nello sviluppo di ogni utility del nuovo standard, il comitato ha applicato alcune direttive:
* Mantenere stabilità e compatibilità con il C++98 e possibilmente anche con il C;
* Preferire l'introduzione di nuove risorse attraverso la libreria standard, anziché estendere il core del linguaggio;
* Prediligere le modifiche che possono evolvere il modo di programmare;
* Rendere il C++ un linguaggio migliore per la programmazione di sistemi e librerie, piuttosto che introdurre nuove risorse dedicate soltanto ad applicazioni particolari;
* Incrementare la sicurezza dei tipi fornendo soluzioni sicure alle correnti soluzioni insicure;
* Incrementare le performance e le capacità di lavorare direttamente con l'hardware;
* Fornire soluzioni adatte al mondo reale;
* Attuare il principio “zero-overhead” (il supporto addizionale richiesto per alcune utility va impiegato solo se la utility è effettivamente utilizzata dal codice);
* Rendere il C++ facile da insegnare e da apprendere a vantaggio dei principianti, senza rimuovere nessuna particolarità necessaria ai programmatori esperti.
L'attenzione verso i principianti è molto importante, sia perché sono e saranno sempre la maggioranza rispetto agli esperti, sia perché molti principianti non intendono approfondire la loro conoscenza del C++, limitandosi ad operare nei campi in cui sono specializzati.

## Estensioni al Linguaggio di programmazione C++

Le attenzioni migliori del comitato per il C++ sono rivolte allo sviluppo del core del linguaggio. È sull'avanzamento dei lavori di questa parte dello standard che dipende la data di presentazione del C++0x.
Spesso si critica il C++ per la gestione non sicura dei tipi. Ma il C++, anche con il prossimo standard, non potrà diventare completamente sicuro nella gestione dei tipi di dato (come il Java), perché, per fare un esempio, comporterebbe l'eliminazione dei puntatori non inizializzati e quindi snaturerebbe tutto il linguaggio. Nonostante ciò sono in molti ad insistere perché lo standard C++ preveda dei meccanismi per la gestione sicura dei puntatori. Per questo motivo il nuovo standard fornirà un supporto per gli smart pointer, ma solo attraverso la libreria standard.
Le aree dove il core del C++ sarà molto migliorato sono quelle per un miglior supporto al multithreading, alla programmazione generica, ed a meccanismi di costruzione ed inizializzazione più flessibili.

### Utilità per il Multitasking

Il comitato del C++ ha intenzione di introdurre per il prossimo standard degli strumenti per la programmazione in multiprocessing e per la programmazione in multithreading.
Un supporto completo per il multiprocessing appare, per il momento, troppo dipendente dal sistema operativo utilizzato e troppo complesso, per essere risolto solo attraverso un'estensione del linguaggio. Si ritiene che il supporto alla programmazione tra processi dovrebbe essere realizzato mediante una libreria di alto livello, da preferirsi rispetto ad una libreria di basso livello (con primitive di sincronizzazione potenzialmente pericolose), poiché il comitato non intende incentivare il programmatore ad utilizzare una libreria standard potenzialmente pericolosa, invece di una libreria sicura anche se non standardizzata.
Nel prossimo standard verranno aggiunti al core del C++ alcune utilità per il multithreading, mentre lo sviluppo di una libreria per i thread resta un obiettivo meno prioritario per il comitato.

#### Esecuzione parallela

Sebbene la proposta vada ancora definita, è possibile che venga introdotto nel prossimo standard (o in futuro) un meccanismo per implementare il costrutto cobegin e coend, utilizzando i thread.
Per il momento non ha molta importanza quale keyword verrà utilizzata per introdurre la nuova notazione. È importante, invece, farsi un'idea di come sarà facile, mediante poche linee di codice, implementare blocchi di istruzioni eseguibili in parallelo.
Tutti i vari blocchi vengono eseguiti in parallelo. Dopo che l'esecuzione di ognuno è terminata, il programma riprende la sua esecuzione con un singolo thread.

#### Chiamata di funzione asincrona

Un'altra proposta ancora da definire, che potrebbe essere introdotta nel prossimo standard (o in futuro), è un meccanismo, mediante thread, per effettuare una chiamata asincrona ad una funzione.
La sintassi probabilmente assomiglierà a quella dell'esempio successivo:

#### Thread-Local Storage

Spesso in ambiente multithread è necessario possedere delle variabili uniche per ogni thread. Questo già avviene per le variabili locali delle funzioni, mentre non avviene per le variabili globali o statiche.
È stato proposto, per il prossimo standard, un nuovo “specificatore di classe di memorizzazione”, che si aggiunge ai numerosi già esistenti (extern, static, register, auto e mutable). Il nuovo specificatore dovrebbe chiamarsi semplicemente thread (al momento nella documentazione ufficiale viene utilizzato __thread).
Gli oggetti thread sono simili agli oggetti globali. Mentre gli oggetti globali hanno un campo di esistenza che copre tutta l'esecuzione del programma, gli oggetti thread hanno un campo di esistenza limitato ad un singolo thread, al cui termine la variabile non può essere più acceduta. Un oggetto thread può essere inizializzato come una qualsiasi variabile di durata statica, eventualmente impiegando un costruttore; se possiede un distruttore, questo verrà chiamato al termine del thread.

#### Operazioni atomiche

Nella multiprogrammazione non c'è solo il problema della sincronizzazione tra i vari thread, spesso un thread ha la necessità di eseguire delle operazioni senza che nessuno lo interrompa, questo può avvenire ed esempio nei sistemi Real-Time quando bisogna operare con una periferica, oppure quando il thread necessita un accesso esclusivo a tutte le variabili globali.
Per eseguire senza interruzioni una serie di operazioni (dette atomiche) è stata proposta la nuova keyword atomic, utilizzabile come nell'esempio seguente:

#### Un nuovo significato per il modificatore di accesso volatile

Nelle versioni di C++ precedenti all'undicesima, il modificatore di accesso volatile informa il compilatore che il valore di una variabile può essere modificato in qualsiasi momento, indipendentemente dalla volontà del thread; per esempio se la variabile è un registro di un dispositivo memory mapped. L'utilizzo di volatile è importante perché limita le ottimizzazioni del compilatore, altrimenti esso assumerebbe che la variabile possa essere modificata solo nel lato sinistro di un'istruzione di assegnamento.
È stato proposto di utilizzare la keyword volatile per indicare anche gli oggetti destinati alla comunicazione tra thread, o comunque condivisi tra più thread. In modo che la scrittura e la lettura di questi oggetti venga protetta automaticamente dal compilatore, mediante sincronizzazione, per evitare errori derivati da un accesso concomitante. Tuttavia questa soluzione al momento appare inappropriata se applicata ad oggetti complessi, ed è ancora in fase di discussione.

### Utilità per le Classi

L'enfasi sulle caratteristiche generali delle classi del C++ è stato il motore principale per il successo di questo linguaggio di programmazione. Per questo è facile immaginare come le innovazioni più significative al core del C++ siano proprio dedicate allo sviluppo di nuove utilità rivolte ad incrementare le performance delle classi.

#### Operatori di conversione espliciti

L'utilizzo implicito degli operatori di conversione di tipo rappresenta una delle insidie più frequenti per un programmatore. Per questo motivo viene consigliato di utilizzare il più possibile operatori di conversione come lo static_cast.
Una possibile soluzione a questo problema sarebbe l'eliminazione del cast implicito da parte del compilatore come suggerito da alcuni puristi (e magari anche del cast C-style, anch'esso fonte di errori). Ma questa soluzione non è praticabile, perché comporterebbe problemi di compatibilità e renderebbe il linguaggio C++ troppo verboso. Per il momento si è pensato di introdurre gli “operatori di conversione espliciti”, questi, a differenza degli operatori di conversione generici, possono essere invocati soltanto attraverso il cast C-style e lo static_cast. L'esempio successivo chiarisce la sintassi e l'utilizzo della nuova utility.

#### Sequence constructors

L'idea di base è quella di permettere l'inizializzazione dei vettori di oggetti definiti dall'utente, facile tanto quanto l'inizializzazione dei vettori di tipi predefiniti, come nell'esempio:
Se invece abbiamo una classe simile alla seguente, nello standard C++98 non esiste la possibilità di inizializzare in modo così diretto e chiaro i suoi membri:
L'idea è quella di introdurre un costruttore speciale a partire da una sequenza di oggetti:
L'inizializzatore di sequenza initializer_list è in realtà una classe template definita come segue:
Ecco una possibile definizione del costruttore di sequenza della classe vettore:

#### Costruttori delegati

Una classe può possedere molti costruttori e spesso questi debbono inizializzare allo stesso modo variabili e classi base ereditate. Capita altrettanto spesso che non sia possibile scrivere una funzione di inizializzazione, perché le classi base ed i riferimenti (&) vanno inizializzati prima di poter accedere al corpo del costruttore. Inoltre il riassegnamento è sconsigliabile per le classi ereditate e impossibile per i riferimenti. Questo porta il programmatore a dover ripetere più volte le stesse istruzioni per ogni costruttore, con risultati disastrosi sul fronte del mantenimento del codice.
È stato pertanto proposto che i costruttori possano richiamare altri costruttori, delegando a questi ultimi il compito di inizializzare l'oggetto:
Nell'esempio si nota come il costruttore di copie ed il costruttore di default siano dei “Delegating Constructors”, perché affidano il compito della costruzione dell'oggetto al costruttore privato coordinata( int, int, int ).

#### Forwarding Constructors

Capita spesso che derivando una classe si vogliano mantenere alcuni dei costruttori della classe base, nello standard C++98 questo è possibile soltanto ridefinendo tutti i costruttori utilizzati. La nuova proposta inserita nel core del linguaggio C++ è tanto semplice quanto utile.
In pratica si tratta solo di estendere l'utilizzo di using, già utilizzabile per gli oggetti membro e per le funzioni membro, anche ai costruttori.

### Diagnosi e dichiarazioni a tempo di compilazione
#### Asserzioni statiche

Le asserzioni sono espressioni booleane che esprimono una proprietà di un oggetto. Lo standard C++98 fornisce due possibilità per testare le asserzioni, la macro ASSERT e la direttiva di preprocessore #error. Però nessuna di queste è adatta per essere utilizzata nei template: la macro testa l'asserzione a tempo di esecuzione, mentre la direttiva di preprocessore testa l'asserzione a tempo di compilazione, ma prima che il template venga istanziato.
La nuova utility prevede l'introduzione di un nuovo metodo per testare le asserzioni a tempo di compilazione, mediante la nuova parola chiave static_assert. La dichiarazione assume la forma seguente:
Ecco alcuni esempi di come la static_assert possa essere utilizzata:
Quando l'espressione costante viene valutata false il compilatore genera un messaggio di errore. Il primo esempio rappresenta un'alternativa alla direttiva di preprocessore #error, nel secondo esempio invece l'asserzione viene valutata per ogni istanziazione della classe template Check.

#### Espressioni Lambda

Le espressioni Lambda sono delle funzioni senza nome definite al momento della chiamata. Per comprendere il vantaggio di utilizzare le espressioni Lambda, immaginiamo una semplice funzione che scandisce un vettore, applicando ad ogni elemento un'operazione:
Volendo utilizzare la stessa funzione con tipi diversi possiamo trasformare la funzione in una funzione template:
Se invece volessimo che la funzione, a seconda delle necessità, eseguisse operazioni diverse, potremmo utilizzare una enumerazione:
Oppure se volessimo un codice più elegante potremmo utilizzare i puntatori a funzione:
Alcuni ritengono che queste soluzioni siano troppe verbose, allora si è pensato di introdurre le “espressioni Lambda”. Se vogliamo resettare tutto il vettore scriveremo semplicemente:
Il segmento(int & x){ x = 0; } è l'espressione lambda che assegna 0 ad ogni elemento del vettore.
Un'espressione lambda presenta la seguente sintassi:
* Sezione 'capture': fra le parentesi quadre è possibile specificare variabili (o riferimenti a variabili) esterne alla lambda di cui tener conto anche all'interno della stessa
* Lista dei parametri che la funzione deve ricevere
* Svolgimento della funzione. Il tipo del valore di ritorno è dedotto dallo svolgimento, o impostato a void se non vi è alcun return.
Tornando all'esempio precedente, è possibile eseguire anche altre operazioni per ogni elemento del vettore, ad esempio visualizzare gli elementi:
Le variabili 'catturate' fra le quadre possono essere utilizzate all'interno delle espressioni Lambda. Nell'esempio successivo si cattura un riferimento a n e si inizializza l'elemento n-esimo al valore di n:
Un'espressione lambda può avere un qualsiasi numero di argomenti. Ad esempio per ordinare un vettore in modo crescente potremo scrivere:
La versione presentata non è la versione definitiva delle funzioni lambda: quanto esposto copre solo in parte l'argomento delle espressioni lambda, ulteriormente migliorate nelle revisioni dello standard C++14 e C++17.

#### Deduzione del tipo: auto e decltype

Spesso la dichiarazione di una variabile non è molto agevole, soprattutto quando si tratta di tipi definiti all'interno di particolari template; prendiamo ad esempio la seguente dichiarazione:
Sebbene a volte sia necessario esplicitare per intero il tipo dell'oggetto che andiamo a creare, in questo caso probabilmente è superfluo, perché può essere ricavato dal tipo di ritorno della funzione.
Utilizzando la parola chiave auto informiamo il compilatore che il tipo della variabile sarà uguale a quello del secondo membro dell'espressione:
Spesso è necessario associare il tipo di una variabile a quello di un'altra, tuttavia il programmatore è obbligato a dichiarare esplicitamente il tipo di ogni variabile che dichiara. Se il problema è l'eccessiva complessità della dichiarazione, allora conviene utilizzare il typedef, ma se l'obiettivo è proprio quello di utilizzare lo stesso tipo di una variabile, qualunque esso sia, è possibile utilizzare la nuova parola chiave decltype:
Il comitato ritiene che il codice scritto utilizzando auto e decltype sia più ordinato e più mantenibile.

### Utilità per i Template

Molti degli sforzi dei ricercatori sono puntati verso il miglioramento della programmazione generica, questo perché è diventata molto popolare e viene utilizzata per esprimere classi sempre più articolate, tanto da mettere in difficoltà i mezzi dell'attuale C++. È necessario quindi che il codice generico possa esprimere soluzioni di maggiore complessità, questo senza sacrificare le caratteristiche che lo hanno reso tanto diffuso: i template sono infatti facili da scrivere, leggere ed impiegare.

#### Alias di template con using

Nelle versioni di C++ precedenti l'undicesima è possibile utilizzare alias di template solo se tutta la lista dei parametri è definita mediante il typedef, né è possibile creare un alias se ci sono dei parametri indefiniti. Sebbene in alcuni casi sia possibile risolvere il problema utilizzando dei parametri di default, in altri l'unica scorciatoia adottabile, che non risolve completamente il problema, è quella di creare un nuovo template che inglobi il template originario. Nell'esempio che segue, infatti, i due tipi dichiarati dalle diverse tecniche di aliasing (generica_ifc_1 e generica_ifc_2) non sono riconosciuti compatibili dal compilatore.
Il problema è importante perché l'aliasing permette un utilizzo più flessibile delle librerie template e quindi anche della STL (Standard Template Library), ad esempio in situazioni come la seguente, sarebbe più comodo avere un alias in cui basti ripetere int una sola volta.
A partire dallo standard C++11 è prevista la possibilità di dichiarare alias di template utilizzando una nuova sintassi, che appunto consenta, per esempio, di scrivere:
Come già permesso per i typedef, questa nuova sintassi potrà essere utilizzata anche all'interno di una classe per creare un alias membro (che quindi potrà essere public, protected o private).

#### Template variadici

Con il nuovo standard sarà introdotta la possibilità dichiarare template con numero arbitrario di parametri. L'impatto più importante sarà senza dubbio quello di poter estendere tutti i controlli, normalmente applicati ai parametri delle normali funzioni durante la compilazione, anche a quelle funzioni con numero arbitrario di parametri.
Per indicare l'elenco dei parametri di lunghezza variabile si utilizza l'operatore “...” che può eventualmente essere seguito dall'identificatore della lista dei parametri:
Sull'identificatore della lista dei parametri può essere applicata una sola operazione di disassemblaggio attraverso l'operatore “...”:
Nel penultimo esempio si è utilizzato la printf come esempio di variadic function, ma possono essere utilizzate anche funzioni con una normale lista di parametri, in questo caso il compilatore utilizza l'overload di my_print corrispondente all'elenco dei parametri inseriti.
Il compilatore, nell'ultimo esempio, espanderà i parametri Secondi all'interno della istanziazione della classe generica, se non esiste un overload del template che accetti due parametri, il codice è malformato e la compilazione da esito negativo. Da notare che il compilatore cercherà di istanziare generica anche se l'elenco dei parametri è vuoto, e quindi cercherà un overload del template generica senza parametri.
Di seguito, un esempio di template utilizzabile per calcolare il tempo di esecuzione di qualunque funzione che non restituisca void:

#### Concept

Spesso i parametri che utilizziamo per un template devono possedere delle determinate caratteristiche, altrimenti rischiamo errori di compilazione, oppure (questo è grave) istanziazioni prive di logica. Nello standard attuale la definizione è l'unico controllo che assumiamo sui parametri di un template, mentre sarebbe più opportuno controllare le sue istanziazioni indipendentemente dalla definizione del template, e viceversa. Per questo fu proposta l'introduzione dei concept: un sistema per migliorare la diagnostica degli errori (quindi le prestazioni offerte dai template), senza perdere capacità espressiva. Tuttavia il gruppo ISO responsabile dello sviluppo dello standard decise di non introdurre i concept poiché ritenuti ancora immaturi rispetto alle scadenze che il gruppo stesso si era prefissato per la standardizzazione della nuova versione del linguaggio; è tuttavia probabile che tale funzionalità verrà proposta per i lavori dello standard successivo.
Osserviamo la funzione template seguente che esegue un ordinamento mediante l'algoritmo di quick sort:
È evidente che i tipi PUNT e result_of<PUNT::operator*> utilizzati in questa funzione devono possedere delle funzioni membro senza le quali la compilazione sarebbe impossibile.
La definizione di un Concept è composta da una lista di parametri, esplicitati come per la dichiarazione di un template, ed il corpo del Concept, una sequenza di semplici dichiarazioni che dipendono dai parametri della dichiarazione.
Il Concept viene introdotto nella definizione del template mediante la keyword where:
Con la stessa sintassi si può utilizzare la where anche all'interno della definizione di un concept per esprimere ulteriori restrizioni sulla combinazione di parametri.
Infine, all'interno della definizione della classe template, sarà possibile utilizzare i type traits (una nuova utility della libreria standard, vedi il paragrafo relativo) per pilotare la compilazione in funzione delle caratteristiche dei parametri assegnati.

#### Parentesi angolari

Con l'introduzione della programmazione generica attraverso i template fu necessario introdurre un nuovo tipo di parentesi. Oltre alle parentesi tonde, quadre e graffe, sono state introdotte le parentesi angolari. Il compilatore, dal momento in cui sono state introdotte le nuove parentesi, deve discriminare quando i caratteri < e > sono utilizzati nelle espressioni logiche, quando invece sono utilizzati come operatori di inserimento (<<) ed estrazione (>>), oppure, per l'appunto, quando sono utilizzati come parentesi angolari; questo ha fatto nascere ovviamente alcune ambiguità:
L'ultimo esempio è un po' astruso ma verificabile. Sono possibili due istanziazioni della classe X: una con I==false ed una con I==true; il codice definisce un'istanza di X in base al valore della relazione costante 1>2 (uguale a false ovviamente), ma il compilatore interpreta > come una parentesi angolare destra ed istanzia la X<true>, quindi il resto del codice diventa privo di senso e la compilazione fallisce.
La soluzione al problema è abbastanza semplice: nel prossimo standard il compilatore, dopo l'apertura di una parentesi angolare sinistra, dovrà interpretare la sequenza di caratteri >> come una doppia parentesi angolare destra, senza lasciarsi trarre in inganno dalle sequenze >= e >>=. Mentre per l'ultimo esempio il programmatore dovrà delimitare dalle parentesi tonde il contenuto della relazione costante.
In questo modo, dopo la parentesi tonda sinistra e fino alla parentesi tonda destra, il compilatore non riconosce più i caratteri <> come parentesi angolari.

### Altre Utility
#### typedef opaco

Questa caratteristica è stata giudicata come non pronta per il C++09, ma da poter riproporre nel futuro dal comitato.
Capita spesso nei programmi di definire più variabili dello stesso tipo, ma che rappresentano grandezze assolutamente non compatibili tra loro. L'esempio più comune è quello di un sistema di coordinate espresso tramite valori double:
In programmi di una certa complessità si avverte la necessità di apportare una distinzione netta tra i tre tipi, soprattutto per ragioni di chiarezza e di mantenibilità del codice:
Questa soluzione in apparenza sembra migliore della precedente ma, in pratica, il compilatore non effettua ancora nessun controllo sui parametri, i quali restano mutuamente sostituibili.
L'unica soluzione possibile è quella di definire tre nuove classi, e programmare tutti gli overload di ogni operatore ammesso. Questa soluzione è ideale, soprattutto se applicata in un programma di grande complessità, perché permette di ottenere un controllo totale sui nuovi tipi; lo sforzo per lo sviluppo dei nuovi oggetti sarebbe comunque poca cosa rispetto ai benefici ottenuti.
Tuttavia se il programmatore non necessita di un controllo così stringente, sarebbe molto più semplice introdurre un nuovo typedef che non crei un semplice alias, ma un nuovo oggetto. Per questo motivo è in fase di sviluppo il cosiddetto “typedef opaco”, mediante il quale sarà possibile creare un nuovo tipo che riceve in eredità tutte le caratteristiche del precedente, senza esserne il sostituto.
Saranno introdotti due tipi di typedef opachi: il typedef public ed il typedef private. Es:
Il primo permetterà ancora la conversione da origine a nuovo (ovviamente non implicita, altrimenti saremmo ancora al punto di partenza) e permetterà ancora una conversione implicita da nuovo a origine, però il nuovo tipo sarà ben distinto dal precedente.
Il secondo è la forma più restrittiva del concetto opaco: per il nuovo tipo, se si vuole permettere delle conversioni con il tipo originario e viceversa, bisognerà definire delle funzioni ad hoc.
La tecnica dei “typedef opachi” non è un metodo per utilizzare qualsiasi classe come se fosse una classe template. I nuovi tipi definiti in questa maniera restano degli alias degli originali seppur con qualche restrizioni.

#### long long int

Fin dai tempi del C c'è sempre stato un tipo integrale di troppo nel Core del linguaggio, in genere int era composto dallo stesso numero di byte della macchina sistema. Lo standard prevedeva per l'int 16 o 32 bit condannando lo short int (abbreviato short) oppure il long int (abbreviato long) ad un ruolo subalterno.
Nei nuovi sistemi a 64 bit i produttori di compilatori hanno messo fine a questa ridondanza di definizione assegnando definitivamente:
* 16 bit -> short int
* 32 bit -> int
* 64 bit -> long int
Tuttavia, nei sistemi a 32 bit, resta radicata l'abitudine dei produttori di compilatori ad utilizzare long long int come numero a 64 bit. Il comitato del C++ si è sempre dimostrato riluttante a standardizzare nuovi tipi fondamentali che non siano anche stati adottati dal comitato del C (che gode di assoluta indipendenza da quello del C++). Ora che la dicitura è diventata uno “standard di fatto”, questo vincolo sembra possa essere finalmente superato. Il comitato C++ ha approvato long long int tra i tipi fondamentali (compreso unsigned long long int).
D'altra parte, in futuro, questa dicitura potrebbe essere ancora utilizzata in sistemi basati su processori con registri a 16 bit per indicare, appunto, numeri a 128 bit.

#### Puntatore nullo

Nello standard pre-11 allo “0” spettava il doppio ruolo di costante intera e di puntatore nullo (soluzione adottata fin dagli albori del C nel 1972).
Per anni i programmatori hanno risposto a questa possibile ambiguità utilizzando la costante “NULL”, al posto dello “0”, anche per rendere il codice più comprensibile. Dal 2011 è stata inclusa una nuova parola chiave (nullptr) riservata esclusivamente per indicare il puntatore nullo.
Il nullptr non può essere assegnato ad un tipo intero, né confrontato con esso, mentre può essere confrontato ed assegnato a qualsiasi puntatore
Resta ovviamente possibile assegnare ad un puntatore la costante “0” per ragioni di compatibilità, tuttavia l'utilizzo di 0 e NULL è sconsigliato in ogni codice che non richieda retrocompatibilità, poiché potrebbe portare ad errori. Ad esempio, consideriamo il codice seguente:

#### La “enum class”

Nello standard C++-98 le enum non sono tipizzate come una classe, inoltre il tipo degli elementi è int e non se ne possono utilizzare altri. Possono essere utilizzati senza dichiararne lo scope e quindi non è possibile dichiarare in due distinte enumerazioni, due elementi con lo stesso nome. Inoltre gli elementi di una enumerazione possono essere convertiti implicitamente ad int e questo è da sempre causa di innumerevoli errori per il programma.
Se il programmatore vuole utilizzare dei tipi più sicuri, è obbligato a sviluppare delle classi come la seguente:
Le uniche azioni permesse tra oggetti di tipo valore sono l'assegnamento ed il confronto, questo dovrebbe mettere al riparo da possibili errori, a patto di convertire ogni valore della enum costanti utilizzato all'interno del codice con un oggetto valore. (Ad essere pignoli questa classe si presta facilmente ad essere trasformata in un template, per essere istanziata a partire da diverse enumerazioni).
A partire dallo standard C++11 non sono più necessarie dichiarazioni verbose come quella precedente per utilizzare una semplice enum ed avere l'appoggio del compilatore per la ricerca di possibili errori sintattici. Sono infatti state introdotte due espressioni riguardanti gli enum:
* Per gli enum classici si potrà indicare esplicitamente il tipo degli elementi della enumerazione. Il tipo dovrà essere un "integral type" (intero o carattere), con o senza segno.
Resta invariata la sintassi per indicare gli elementi della enum.
* Inoltre è stato introdotto un nuovo tipo di enumerazione: la enum class, fortemente tipizzata: non sono supportati i cast impliciti e, per indicare ogni elemento, è sempre necessario indicarne lo scope. Anche per la enum è possibile indicare esplicitamente il tipo degli elementi; se omesso sarà utilizzato int.

### Ranged-for

A partire dal C++11 è stato introdotto il ranged for, un metodo più veloce per iterare attraverso gli elementi di un array o di un container. Affinché un oggetto sia iterabile mediante un range-based for è necessario che disponga di un metodo begin e un metodo end, o che esista un overload di std:begin e std::end per la classe dell'oggetto.
La sintassi di un range-based for è for ( tipo nome_elemento : nome_container) { espressioni... }; una caratteristica molto comoda di questo ciclo è che l'elemento dichiarato è di tipo *container::iterator, pertanto è possibile lavorare direttamente sull'elemento invece che sull'iteratore.

## Estensioni alla libreria standard C++

Dalla Standard library del C++0x arriveranno le novità più ardite, anche se, in realtà, quasi tutte le nuove librerie non necessitano dell'aggiornamento del core e potrebbero funzionare anche sullo standard C++ corrente.
La maggior parte delle librerie che saranno introdotte sono definite nel documento “Technical Report on C++ Library Extensions” (chiamato anche TR1), la cui stesura definitiva risale al 2005. Queste librerie sono già state adottate da alcuni compilatori e possono essere richiamate mediante il “namespace std::tr1”.
È in preparazione un secondo technical report (TR2) ma sicuramente verrà completato dopo la standardizzazione del C++0x. Per questa ragione il paragrafo corrente referenzia esclusivamente alcune delle librerie più significative introdotte attraverso il TR1.

### Tuple

Le tuple sono collezioni di dimensioni prestabilite composte da oggetti di tipo eterogeneo. Gli elementi di una tupla possono essere un qualsiasi tipo di oggetto.
Questa utilità viene implementata nell'header <tuple> e beneficia di alcune estensioni del linguaggio C++, come:
* template con lista di argomenti di lunghezza variabile,
* riferimenti a riferimenti,
* argomenti di default per le funzioni template (disponibili solo per le classi).
Ecco la definizione di tupla nell'header <tuple>:
Esempio di definizione ed uso di una tupla:
È possibile creare la tupla prova senza definirne il suo contenuto, ma questo solo se tutti gli oggetti della tupla possiedono il costruttore di default; inoltre si può assegnare una tupla ad un'altra: se le tuple sono dello stesso tipo, sarà necessario che tutti gli oggetti possiedano il costruttore di copie; se gli oggetti non corrispondono, sarà necessario che quelli del 2º membro siano convertibili a quelli del 1º, oppure che i tipi del 1º membro abbiano un costruttore adeguato:
Sono anche disponibili gli operatori di confronto (tra tuple con uguale numero di elementi e fra tuple da due elementi e std::pair) ed inoltre sono disponibili due espressioni per controllare le caratteristiche delle tuple (solo a tempo di compilazione):
* tuple_size<T>::value Ritorna il valore del numero di elementi della tupla di tipo T.
* tuple_element<I, T>::type Ritorna il tipo dell'elemento numero I della tupla di tipo T.

### Tabelle di Hash

L'inserimento nella libreria standard del C++ delle tabelle di Hash (i contenitori associativi non ordinati) è stata una delle richieste più frequenti. Sebbene queste soluzioni diano rendimenti inferiori rispetto agli alberi bilanciati se utilizzate nel caso peggiore (ossia in presenza di molte collisioni), le loro performance sono migliori in molte applicazioni reali.
La gestione delle collisioni viene amministrata soltanto mediante linear chaining. Questo perché il comitato non ha ritenuto opportuno standardizzare soluzioni di open addressing che presentano parecchi problemi intrinseci (soprattutto quando è ammessa la cancellazione di elementi). A causa delle possibili omonimie con librerie non standard, che nel frattempo hanno colmato la mancanza di una libreria standard per le tabelle di Hash, è stato utilizzato il prefisso “unordered” invece di “hash”.
La nuova utility prevede 4 tipi di tabelle di Hash, differenti a seconda che accettino o no più elementi con la stessa chiave (chiavi equivalenti o chiavi uniche) ed a seconda che associno o no un valore arbitrario alla chiave.
| Tipo di tabella di hash | Mappatura arbitraria | Chiavi equivalenti |
| unordered_set | | |
| unordered_multiset | | X |
| unordered_map | X | |
| unordered_multimap | X | X |
Le nuove classi sono modellate sul concetto di container, pertanto ne implementano tutte le funzioni, comprese quelle necessarie per accedere agli elementi come: insert, erase, begin, end.
Per utilizzare le tabelle di hash è necessario includere gli headers <unordered_set> e <unordered_map> secondo necessità.

### Espressioni regolari

A partire dal C++11 la libreria standard ha incluso una propria libreria per le gestione delle espressioni regolari. La nuova libreria, definita nel nuovo header <regex>, consiste in una coppia di nuove classi:
* le espressioni regolari sono rappresentate dalle istanze della classe template basic_regex;
* le corrispondenze sono rappresentate dalle istanze della classe template match_results.
Per la ricerca si utilizza la funzione regex_search, mentre per la ricerca e la sostituzione si utilizza regex_replace, che fornisce una nuova stringa corretta come risultato. Gli algoritmi regex_search e regex_replace ricevono come input una espressione regolare ed una stringa di caratteri e scrivono le corrispondenze trovate nella struttura match_results.
Esempio di utilizzo di match_results:
La libreria “regex” non richiede l'alterazione di nessun header esistente e nessuna estensione del linguaggio.

### Puntatori smart per usi generici

La gestione dell'allocazione dinamica della memoria è sempre stata, fin dai primi computer, un punto delicato della programmazione. Molti moderni linguaggi di programmazione (tipo il Java) offrono strumenti per la gestione automatica della memoria.
I puntatori ordinari del C++ hanno molte interessanti proprietà:
* è possibile copiarli,
* assegnarli,
* utilizzarne il loro valore,
* utilizzare il void * come puntatore generico,
* convertirli ad una delle classi base attraverso un cast statico,
* convertirli ad una delle classi derivate attraverso un cast dinamico.
Mentre i principali difetti dei puntatori ordinari del C++ sono:
* la gestione manuale obbligata per gli oggetti allocati dinamicamente,
* possono riferirsi ad un indirizzo non valido o non allocato della memoria.
I nuovi smart pointer mantengono le caratteristiche di forza dei puntatori ordinari eliminando le loro debolezze.
Utilizzando i puntatori shared_ptr la proprietà dell'oggetto viene ripartita egualmente a tutte le copie, all'ultima istanza rimasta viene delegata la responsabilità di distruggere l'oggetto. Per conoscere il numero di puntatori che fanno riferimento allo stesso oggetto è possibile utilizzare la use_count, una funzione membro di shared_ptr. La funzione membro reset permette di cancellare lo smart pointer. Un puntatore resettato si dice vuoto, quindi la sua funzione use_count ritorna sempre zero. Il puntatore weak_ptr non incide sul ciclo di vita dell'oggetto puntato, questo significa che in ogni momento è possibile che il weak_ptr venga invalidato. In questo modo è permesso a qualsiasi funzione o classe di mantenere un riferimento ad un oggetto senza influenzarne il ciclo di vita, a discapito però di una maggiore difficoltà di implementazione del codice.
Esempio di utilizzo dello shared_ptr:
Un terzo smart pointer è lo unique_ptr: un puntatore tale da esser l'unico detentore dell'area di memoria che ha allocato. Non è possibile copiare uno unique_ptr : è solo possibile trasferire la proprietà da un puntatore all'altro mediante il supporto della funzione std::move.
È possibile utilizzare gli smart pointers includendo l'header <memory>; è inoltre buona norma rimpiazzare l'uso di auto_ptr, deprecato in questo sin da questo standard con i nuovi smart pointers.

### Utilità estensibile per numeri casuali

I computer hanno per definizione comportamento deterministico, tuttavia alcune applicazioni richiedono un comportamento non deterministico (anche se solo in apparenza) veicolato dalla generazione di numeri casuali.
La sola utilità standard presente prima del 2011 era la funzione rand, ma non è ben definita e la sua implementazione è delegata interamente ai produttori dei compilatori. Pertanto sono state introdotte nuove utilità per generare numeri casuali nell'header <random>.
I generatori di numeri casuali sono costituiti da uno stato interno, ed una funzione che elabora il risultato e porta il generatore allo stato successivo. Queste due caratteristiche costituiscono il motore del generatore. Un'altra fondamentale caratteristica è infine la distribuzione dei risultati, ossia l'intervallo e la densità della variabile aleatoria.
Attraverso il template variate_generator è possibile creare un generatore di numeri casuali selezionando il motore e la distribuzione desiderata. Si può scegliere tra i motori e le distribuzioni fornite dallo standard, oppure utilizzare mezzi propri.
* Motori per numeri pseudocasuali
Nella nuova libreria verranno introdotti alcuni motori per la generazione di numeri pseudocasuali. Questi sono tutti dei template, in questo modo l'utente può personalizzarli come preferisce. Lo stato interno dei motori pseudocasuali è determinato attraverso un seme (generalmente un insieme di variabili). L'apparente casualità è dovuta solo dalla limitata percezione dell'utente.
| classe template | int/float | qualità | velocità | dimensione stato* |
| linear_congruential | int | bassa | media | 1 |
| substract_with_carry | entrambi | media | veloce | 25 |
| mersenne_twister | int | buona | veloce | 624 |
* Moltiplicare il valore per la dimensione in byte del tipo utilizzato.
Le prestazioni di questi motori possono essere incrementate utilizzando la classe template discard_block, oppure possono essere combinate utilizzando la classe template xor_combine. Per comodità nell'header <random> sono definite anche alcune istanze standard di motori; un esempio è la classe mt19937 istanziata su base mersenne_twister:
* Motore per numeri non deterministici
Attraverso la classe random_device è possibile generare numeri non deterministici di tipo unsigned int. La sua implementazione richiederà l'utilizzo di un dispositivo il cui stato sia indipendente dal sistema che ospita l'applicazione (ad esempio da un contatore esterno non sincronizzato, oppure un trasduttore particolare) e richiederà anche l'impiego di un tradizionale motore pseudocasuale per, come si usa dire, “temprare il risultato”.
* Distribuzioni dei numeri casuali
La libreria definisce parecchi tipi di distribuzioni, dalle distribuzioni uniformi a quelle definite dalla teoria della probabilità: uniform_int, bernoulli_distribution, geometric_distribution, poisson_distribution, binomial_distribution, uniform_real, exponential_distribution, normal_distribution e gamma_distribution. Ovviamente l'utente è libero di instanziare come preferisce le distribuzioni standard oppure di utilizzare una sua distribuzione compatibile.
Ecco un semplice esempio di implementazione:

### Funzioni matematiche speciali

L'header <math> definisce alcune funzioni matematiche abbastanza comuni:
* trigonometriche: sin, cos, tan, asin, acos, atan e atan2;
* iperboliche: sinh, cosh, tanh, asinh, acosh, atanh;
* esponenziali: exp, exp2, frexp, ldexp, expm1;
* logaritmiche: log10, log2, logb, ilogb, log1p;
* potenze: pow, sqrt, cbrt, hypot;
* speciali: erf, erfc, tgamma, lgamma.
La proposta era di aggiungere nuove funzioni alla categoria ‘speciali' per colmare parecchie lacune che costringono ad utilizzare librerie non standardizzate, tuttavia tale cambiamento non è stato approvato per la versione finale del C++11. Chiaramente l'utilizzo di queste funzioni sarebbe stato limitato all'ambito ingegneristico ed alle discipline scientifiche.
La tabella seguente riporta le 23 funzioni approvate per lo standard C++11.
| Nome della funzione | Prototipo della funzione | Espressione matematica |
| Polinomi associati di Laguerre | double assoc_laguerre(unsigned n, unsigned m, double x) ; | ${L_{n}}^{m}(x)=(-1)^{m}{\frac {d^{m}}{dx^{m}}}L_{n+m}(x),{\text{ per }}x\geq 0$ |
| Polinomi associati di Legendre | double assoc_legendre(unsigned l, unsigned m, double x) ; | ${P_{l}}^{m}(x)=(1-x^{2})^{m/2}{\frac {d^{m}}{dx^{m}}}P_{l}(x),{\text{ per }}x\geq 0$ |
| Funzione beta di Eulero | double beta(double x, double y) ; | $\mathrm {B} (x,y)={\frac {\Gamma (x)\Gamma (y)}{\Gamma (x+y)}}$ |
| Integrale ellittico completo di prima specie | double comp_ellint_1(double k) ; | $K(k)=F\left(k,\textstyle {\frac {\pi }{2}}\right)=\int _{0}^{\frac {\pi }{2}}{\frac {d\theta }{\sqrt {1-k^{2}\sin ^{2}\theta }}}$ |
| Integrale ellittico completo di seconda specie | double comp_ellint_2(double k) ; | $E\left(k,\textstyle {\frac {\pi }{2}}\right)=\int _{0}^{\frac {\pi }{2}}{\sqrt {1-k^{2}\sin ^{2}\theta }}\;d\theta$ |
| Integrale ellittico completo di terza specie | double comp_ellint_3(double k, double nu) ; | $\Pi \left(\nu ,k,\textstyle {\frac {\pi }{2}}\right)=\int _{0}^{\frac {\pi }{2}}{\frac {d\theta }{(1-\nu \sin ^{2}\theta ){\sqrt {1-k^{2}\sin ^{2}\theta }}}}$ |
| Funzione ipergeometrica confluente | double conf_hyperg(double a, double c, double x) ; | $F(a,c,x)={\frac {\Gamma (c)}{\Gamma (a)}}\sum _{n=0}^{\infty }{\frac {\Gamma (a+n)x^{n}}{\Gamma (c+n)n!}}$ |
| Funzione cilindrica di Bessel modificata regolarmente | double cyl_bessel_i(double nu, double x) ; | $I_{\nu }(x)=i^{-\nu }J_{\nu }(ix)=\sum _{k=0}^{\infty }{\frac {(x/2)^{\nu +2k}}{k!\;\Gamma (\nu +k+1)}},{\text{ per }}x\geq 0$ |
| Funzione cilindrica di Bessel di prima specie | double cyl_bessel_j(double nu, double x) ; | $J_{\nu }(x)=\sum _{k=0}^{\infty }{\frac {(-1)^{k}\;(x/2)^{\nu +2k}}{k!\;\Gamma (\nu +k+1)}},{\text{ per }}x\geq 0$ |
| Funzione cilindrica di Bessel modificata irregolarmente | double cyl_bessel_k(double nu, double x) ; | ${\begin{aligned}K_{\nu }(x)&=\textstyle {\frac {\pi }{2}}i^{\nu +1}{\bigJ_{\nu }(ix)+iN_{\nu }(ix){\big )}\\&={\begin{cases}\displaystyle {\frac {I_{-\nu }(x)-I_{\nu }(x)}{\sin \nu \pi }},&{\text{ per }}x\geq 0{\text{ e }}\nu \notin \mathbb {Z} \\[10pt]\displaystyle {\frac {\pi }{2}}\lim _{\mu \to \nu }{\frac {I_{-\mu }(x)-I_{\mu }(x)}{\sin \mu \pi }},&{\text{ per }}x<0{\text{ e }}\nu \in \mathbb {Z} \\\end{cases}}\end{aligned}}$ |
| Funzione cilindrica di Neumann Funzione cilindrica di Bessel di seconda specie | double cyl_neumann(double nu, double x) ; | $N_{\nu }(x)={\begin{cases}\displaystyle {\frac {J_{\nu }(x)\cos \nu \pi -J_{-\nu }(x)}{\sin \nu \pi }},&{\text{ per }}x\geq 0{\text{ e }}\nu \notin \mathbb {Z} \\[10pt]\displaystyle \lim _{\mu \to \nu }{\frac {J_{\mu }(x)\cos \mu \pi -J_{-\mu }(x)}{\sin \mu \pi }},&{\text{ per }}x<0{\text{ e }}\nu \in \mathbb {Z} \\\end{cases}}$ |
| Integrale ellittico incompleto di prima specie | double ellint_1(double k, double phi) ; | $F(k,\phi )=\int _{0}^{\phi }{\frac {d\theta }{\sqrt {1-k^{2}\sin ^{2}\theta }}},{\text{ per }}\left|k\right|\leq 1$ |
| Integrale ellittico incompleto di seconda specie | double ellint_2(double k, double phi) ; | $\displaystyle E(k,\phi )=\int _{0}^{\phi }{\sqrt {1-k^{2}\sin ^{2}\theta }}d\theta ,{\text{ per }}\left|k\right|\leq 1$ |
| Integrale ellittico incompleto di terza specie | double ellint_3(double k, double nu, double phi) ; | $\Pi (k,\nu ,\phi )=\int _{0}^{\phi }{\frac {d\theta }{\left(1-\nu \sin ^{2}\theta \right){\sqrt {1-k^{2}\sin ^{2}\theta }}}},{\text{ per }}\left|k\right|\leq 1$ |
| Integrale esponenziale | double expint(double x) ; | ${\mbox{E}}i(x)=-\int _{-x}^{\infty }{\frac {e^{-t}}{t}}\,dt$ |
| Polinomi di Hermite | double hermite(unsigned n, double x) ; | $H_{n}(x)=(-1)^{n}e^{x^{2}}{\frac {d^{n}}{dx^{n}}}e^{-x^{2}}$ |
| Serie ipergeometrica | double hyperg(double a, double b, double c, double x) ; | $F(a,b,c,x)={\frac {\Gamma (c)}{\Gamma (a)\Gamma (b)}}\sum _{n=0}^{\infty }{\frac {\Gamma (a+n)\Gamma (b+n)}{\Gamma (c+n)}}{\frac {x^{n}}{n!}}$ |
| Polinomi di Laguerre | double laguerre(unsigned n, double x) ; | $L_{n}(x)={\frac {e^{x}}{n!}}{\frac {d^{n}}{dx^{n}}}\left(x^{n}e^{-x}\right),{\text{ per }}x\geq 0$ |
| Polinomi di Legendre | double legendre(unsigned l, double x) ; | $P_{l}(x)={1 \over 2^{l}l!}{d^{l} \over dx^{l}}(x^{2}-1)^{l},{\text{ per }}\left|x\right|\leq 1$ |
| Funzione zeta di Riemann | double riemann_zeta(double x) ; | $\mathrm {Z} (x)={\begin{cases}\displaystyle \sum _{k=1}^{\infty }k^{-x},&{\text{per }}x>1\\[10pt]\displaystyle 2^{x}\pi ^{x-1}\sin \left({\frac {x\pi }{2}}\right)\Gamma (1-x)\zeta (1-x),&{\text{per }}x<1\\\end{cases}}$ |
| Funzione sferica di Bessel di prima specie | double sph_bessel(unsigned n, double x) ; | $j_{n}(x)={\sqrt {\frac {\pi }{2x}}}J_{n+1/2}(x),{\text{ per }}x\geq 0$ |
| Funzione sferica associata di Legendre | double sph_legendre(unsigned l, unsigned m, double theta) ; | $Y_{l}^{m}(\theta ,0){\text{ where }}Y_{l}^{m}(\theta ,\phi )=(-1)^{m}\left[{\frac {(2l+1)}{4\pi }}{\frac {(l-m)!}{(l+m)!}}\right]^{1 \over 2}P_{l}^{m}(cos\theta )e^{im\phi },{\text{ per }}|m|\leq l$ |
| Funzione sferica di Neumann Funzione sferica di Bessel di seconda specie | double sph_neumann(unsigned n, double x) ; | $n_{n}(x)=\left({\frac {\pi }{2x}}\right)^{\frac {1}{2}}N_{n+{\frac {1}{2}}}(x),{\text{ per }}x\geq 0$ |
Ad ogni funzione è sufficiente aggiungere il suffisso ‘f' per ottenere la versione ‘float' ed il suffisso ‘l' per la versione ‘long double'. Es:

### Wrapper reference

Il wrapper reference viene ottenuto da un'istanza della classe template reference_wrapper nell'header <utility>, il suo utilizzo è simile al riferimento ‘&' previsto dal linguaggio C++. Per ottenere un wrapper reference da un oggetto qualsiasi si utilizza la funzione template ref (per un riferimento costante si usa cref).
Il wrapper reference è utile soprattutto per le funzioni template quando vogliamo che ottengano un riferimento ai loro parametri invece di utilizzarne una copia:

### Wrapper polimorfi per oggetti funzione

I wrapper polimorfi per oggetti funzione (Polymorphic Function Object Wrapper) sono simili ai puntatori a funzione per semantica e sintassi, ma il loro utilizzo è meno vincolato e possono riferirsi indistintamente a qualsiasi funzione che possa essere chiama con argomenti compatibili con quelli del wrapper.
Attraverso l'esempio seguente è possibile comprenderne le caratteristiche:
La classe template function è definita all'interno dell'header <functional>.

### I type traits per la metaprogrammazione

La metaprogrammazione consiste nel creare un programma che crei o modifichi un altro programma (o se stesso). Questo può avvenire a tempo di compilazione oppure a tempo di esecuzione. Il comitato del C++ ha deciso di introdurre una libreria che consenta la metaprogrammazione a tempo di compilazione attraverso i template.
Ecco un ottimo esempio di quello che si può già ottenere, con lo standard attuale, attraverso la metaprogrammazione: una ricorsione di istanziazioni di template per il calcolo di una potenza.
Molti algoritmi possono essere utilizzati indistintamente per diversi tipi di dati, per questo motivo sono stati inseriti nello standard C++ i template, in modo da supportare la programmazione generica e rendere più compatto e gestibile il codice. Tuttavia capita spesso di imbattersi in algoritmi che necessitano di informazioni sui dati utilizzati. Queste informazioni possono essere ricavate durante l'istanziazione di una qualsiasi classe template utilizzando i type traits.
I type traits sono moltissimi e possono identificare la categoria di un oggetto e tutte le caratteristiche di una classe (o di una struttura). Sono definiti nel nuovo header <type_traits>.
Nell'esempio seguente c'è la funzione template ‘elabora' che a seconda del tipo di dati inseriti istanzierà uno dei due algoritmi proposti (funzione.do_it).
Attraverso i type traits, definiti nell'header <type_transform>, è possibile effettuare anche delle operazioni di trasformazioni sui tipi (lo static_cast ed il const_cast non sono sufficienti all'interno di un template).
Questo tipo di programmazione permette di ottenere un codice elegante e conciso; il vero punto debole di queste tecniche è il debugging: disagevole a tempo di compilazione e molto difficile durante l'esecuzione del programma.

### Metodo Uniforme per determinare i tipi di ritorno di un oggetto funzione

Determinare (a tempo di compilazione) il tipo di ritorno di una funzione oggetto template, soprattutto se dipende dai parametri della funzione stessa, non è sempre intuitivo.
Prendiamo in esempio il codice seguente:
Istanziando la classe template calcolo, utilizzando come parametro la classe chiara (ossia istanziando calcolo<chiara>), la funzione oggetto di calcolo avrà sempre lo stesso tipo di ritorno di quello della funzione oggetto di chiara.
Se invece istanziamo la classe calcolo utilizzando la classe confusa (ossia istanziando calcolo<confusa>):
Il tipo di ritorno della funzione oggetto di calcolo non sarà lo stesso di quello della classe confusa (potrà esserci una conversione da int a double o viceversa, a seconda dell'istanziazione di calculus<confused>.operator).
La nuova libreria, proposta per il prossimo standard, introduce la classe template result_of, che permette al programmatore di determinare ed utilizzare il tipo di ritorno di una funzione oggetto per qualsiasi dichiarazione. Nella versione corretta calcolo_ver2 viene impiegata la nuova utility per ricavare il tipo di ritorno della funzione oggetto:
In questo modo nelle istanziazioni della funzione oggetto di ‘calcolo_ver2<confusa>' non ci saranno più conversioni.
Il problema di determinare il tipo di ritorno di una chiamata ad un oggetto funzione è un sottoinsieme del problema più generale di determinare il tipo di risultato di un'espressione. Questo problema potrebbe essere risolto in futuro espandendo le funzionalità della typeof a tutte le casistiche possibili.