La vecchia tecnica Microsoft
La buona vecchia tecnica Microsoft ha servito milioni di applicazioni, quindi è definitivamente considerato un approccio valido e comprovato.
Tre osservazioni:
-
Microsoft utilizza questa compilazione condizionale non solo i pochi elementi fondamentali (TCHAR, TEXT, ...), ma anche per molte altre funzioni relative alle stringhe (vedere l'esempio nell'articolo MSDN) in modo che questo possa lavorare in modo coerente.
-
Devi stare attento alla combinazione di macro con namespace. Ad esempio Str()
ha l'aspetto di una funzione normale, ma è una macro definita globalmente e non limitata al tuo spazio dei nomi (e da utilizzare senza prefisso dello spazio dei nomi). Ti suggerirei di usare maiuscole per rendere esplicito
- Se inizi ora con una nuova base di codice, suggerirei di adottare la raccomandazione di Meyer di preferire l'alias di tipo su typedef.
Variante ridondante
Come in C ++ string
/ wstring
, stringstream
/ wstringstream
, ecc ... sono solo char
/ wchar_t
specializzazioni di basic_string<X>
/ basic_stringstream<X>
, definirei il tipi da utilizzare in base al tipo di carattere sottostante che si desidera:
namespace mine {
#ifdef UNICODE
using Char = wchar_t;
#define Str(s) L##s
#else
using Char = char;
#define Str(s) s
#endif
using String = std::basic_string<Char>;
using StringStream = std::basic_stringstream<Char>;
// ... a lot more but only once
}
Demo
Se necessario, potresti facilmente passare a char32_t
se volessi lavorare con un Unicode a 32 bit su tutte le piattaforme (attualmente wchar_t su Windows è 16 bit e usa la codifica UTF16, mentre su linux è a 32 bit e UTF32) come si può usare u32string
).
Compilazione condizionale
In teoria si potrebbe immaginare una decisione runtime se eseguire unicode o meno. Ma per raggiungere questo obiettivo è necessario creare tutti gli oggetti utilizzando una fabbrica astratta . Questo sembra molto doloroso e complesso. Non parliamo del codice gonfiato con tutte le funzioni di stringa in doppio.
Un altro approccio potrebbe essere l'uso di alcuni modelli per definire i tipi in fase di compilazione utilizzando un modello intelligente. Ma alla fine avresti bisogno di fare affidamento su alcune macro, che potresti definire negli script di compilazione per automatizzare la creazione di tutte le versioni. Come alla fine ti fiderai di loro, perché non facilitare l'approccio e usarli per quello che dovrebbero fare!