Ho lavorato per un bel po 'nel mantenere un livello di compatibilità avanti e indietro nei miei programmi C ++, fino a quando alla fine ho dovuto creare un toolkit di libreria , che sto preparando per il rilascio è già stato rilasciato. In generale, purché si accetti che non si otterrà una compatibilità in avanti "perfetta" né nelle funzionalità (alcune cose non possono essere emulate in avanti) non nella sintassi (probabilmente si dovranno usare macro, spazi dei nomi alternativi per alcune cose) allora sei pronto.
Esistono molte funzioni che possono essere emulate in C ++ 03 a un livello sufficiente per l'uso pratico e senza tutte le seccature che ne derivano, ad es .: Boost. Diamine, anche la proposta di standard C ++ nullptr
suggerisce un backport C ++ 03. E poi c'è TR1 per esempio per tutto ciò che riguarda C ++ 11-ma-abbiamo-avuto-anteprime-per-anni. Non solo, alcune caratteristiche di C ++ 14 come asserire varianti, funzioni trasparenti e optional
possono essere implementate in C ++ 03!
Le uniche due cose che so che non è assolutamente possibile eseguire il backport sono i modelli constexpr e variadic.
Per quanto riguarda l'intera questione dell'aggiunta di cose allo spazio dei nomi std
, la mia opinione è che non importa - affatto. Pensa a Boost, una delle librerie C ++ più importanti e pertinenti e alla loro implementazione di TR1: Boost.Tr1. Se vuoi migliorare il C ++, rendilo compatibile in avanti con C ++ 11, per definizione lo stai trasformando in qualcosa che non è C ++ 03, quindi bloccarti su uno Standard che intendi evitare o lasciare indietro è , in poche parole, controproducente. I puristi si lamenteranno, ma per definizione non è necessario preoccuparsene.
Certo, solo perché non seguirai lo (03) Standard dopo tutto non significa che non puoi provare, o vorrai andare in giro rompendolo. Non è questo il punto. Fintanto che manterrai un controllo molto attento su ciò che viene aggiunto allo std
spazio dei nomi e avrai il controllo degli ambienti in cui viene utilizzato il tuo software (es .: esegui i test!), Non dovrebbe esserci alcun danno non trattabile. Se possibile, definisci tutto in uno spazio dei nomi separato e aggiungi solo using
direttive allo spazio dei nomi in std
modo da non aggiungere altro al di là di ciò che "assolutamente" deve avere. Che, IINM, è più o meno ciò che fa Boost.TR1.
Aggiornamento (2013) : come richiesta della domanda originale e vedendo alcuni dei commenti che non posso aggiungere a causa della mancanza di rep, ecco un elenco di funzionalità C ++ 11 e C ++ 14 e il loro grado di portabilità a C ++ 03:
nullptr
: pienamente attuabile dato il backport ufficiale del Comitato; probabilmente dovrai fornire anche alcune specializzazioni di type_traits in modo che sia riconosciuto come tipo "nativo".
forward_list
: completamente implementabile, sebbene il supporto dell'allocatore si basi su ciò che può fornire la tua implmenentazione Tr1.
- Nuovi algoritmi (partition_copy, ecc.): Completamente implementabili.
- Costruzioni di container da sequenze di parentesi graffe (es . :)
vector<int> v = {1, 2, 3, 4};
: pienamente implementabili, anche se più vocali di quanto si vorrebbe.
static_assert
: quasi completamente implementabile quando implementato come macro (dovrai solo stare attento alle virgole).
unique_ptr
: quasi completamente implementabile, ma avrai anche bisogno del supporto del codice chiamante (per memorizzarlo in contenitori, ecc.); vedi comunque sotto.
- rvalue-reference: quasi completamente implementabile a seconda di quanto ci si aspetta da loro (es .: Boost Move).
- Per ogni iterazione: quasi completamente implementabile, la sintassi differirà leggermente.
- utilizzo delle funzioni locali come argomenti (ad es .: trasformazione): quasi completamente implementabile, ma la sintassi sarà abbastanza diversa - ad esempio, le funzioni locali non sono definite nel sito di chiamata ma subito prima.
- operatori di conversione esplicita: implementabile a livelli pratici (rendere esplicita la conversione), vedere "esplicito_cast" di C ++ di Imperfect ; ma l'integrazione con funzionalità linguistiche come
static_cast<>
potrebbe essere quasi impossibile.
- forwarding di argomenti: implementabile a livelli pratici dato quanto sopra sui riferimenti rvalue, ma dovrai fornire N sovraccarichi alle tue funzioni prendendo argomenti forwardable.
- mossa: implementabile a livelli pratici (vedi i due aboves). Ovviamente, dovresti usare contenitori e oggetti modificatori per trarne profitto.
- Allocatori con ambito: non realmente implementabili a meno che l'implementazione di Tr1 non possa essere d'aiuto.
- tipi di caratteri multibyte: non implementabili se il tuo Tr1 non ti supporta. Ma per lo scopo previsto è meglio fare affidamento su una libreria appositamente progettata per affrontare la questione, come l'ICU, anche se si utilizza C ++ 11.
- Elenchi di argomenti variabili: implementabili con una certa seccatura, prestare attenzione all'inoltro degli argomenti.
noexcept
: dipende dalle caratteristiche del tuo compilatore.
- Nuova
auto
semantica e decltype
: dipende dalle caratteristiche del tuo compilatore - ad es __typeof__
. : .
- tipi interi di dimensioni (
int16_t
, ecc.): dipende dalle funzionalità del compilatore oppure è possibile delegare a Portable stdint.h.
- attributi di tipo: dipende dalle caratteristiche del tuo compilatore.
- Elenco di inizializzatori: non implementabile a mia conoscenza; tuttavia, se si desidera inizializzare i contenitori con sequenze, vedere quanto sopra in "costruzioni di contenitori".
- Alias dei modelli: non implementabile per quanto ne sappia, ma è comunque una funzione non necessaria e
::type
nei modelli abbiamo sempre avuto
- Modelli variabili: non implementabili a mia conoscenza; la chiusura è l'impostazione predefinita dell'argomento template, che richiede N specializzazioni, ecc.
constexpr
: Non implementabile per quanto ne so.
- Inizializzazione uniforme: non implementabile per quanto ne sappia , ma l' inizializzazione predefinita del costruttore può essere implementata come valore inizializzato da Boost.
- C ++ 14
dynarray
: completamente implementabile.
- C ++ 14
optional<>
: quasi completamente implementabile a condizione che il compilatore C ++ 03 supporti le configurazioni di allineamento.
- Funzioni trasparenti C ++ 14: quasi completamente implementabili, ma il codice client probabilmente dovrà usare esplicitamente, ad esempio:
std::less<void>
per farlo funzionare.
- C ++ 14 nuove varianti di assert (come
assure
): completamente implementabili se si desidera assert, quasi completamente implementabili se si desidera abilitare i tiri.
- Estensioni di tupla in C ++ 14 (ottieni l'elemento tupla per tipo): completamente implementabile e puoi persino far sì che non riesca a compilare con i casi esatti descritti nella proposta di funzionalità.
(Dichiarazione di non responsabilità: molte di queste funzionalità sono implementate nella mia libreria di backport C ++ che ho collegato sopra, quindi penso di sapere di cosa sto parlando quando dico "pienamente" o "quasi completamente".)