ホーム < ゲームつくろー! < Programming TIPs編

その14 UNICODEで分けないtstring型を宣言する


 Visual C++には文字セットとしてUnicode対応版とマルチバイト文字列対応版があります。これはプロジェクトのプロパティの構成プロパティにある「文字セット」で設定できます。

 Unicode文字セットの場合2バイト文字を扱う事になります。型は通常wchar_t型です。一方マルチバイト文字セットは1バイト文字を扱うので方はchar型です。プログラマはプロジェクトの文字セットごとにこれを使い分ける必要があります。これは極めて面倒です。そこでVisual C++にはTCHAR型が用意されています。TCHAR型自体は次のように定義されています:

tchar.h
#ifdef _UNICODE
typedef wchar_t TCHAR;
#else
typedef char TCHAR;
#endif

 プロジェクトがUnicode文字セットの場合_UNICODEマクロが自動的に定義されます。よって#ifdefで_UNICODEを判別して、文字コードで型を分けているわけです。これにより、プログラマはプロジェクトの文字セットをTCHAR型で吸収してプログラムを構築できます。


 ところで、文字列を便利に扱えるライブラリにstd::stringがありますが、これはマルチバイト文字専用です。つまり、

wchar_t *c = L"これは2バイト文字です";

std::string str = c;

という代入はできません。では2バイト文字用のstringはというとstd::wstringというのがあります。これだと、

wchar_t *c = L"これは2バイト文字です";

std::wstring str = c;

と代入ができます。ではTCHAR型で宣言した場合はどうでしょう?

TCHAR *c = _T("これは2バイト文字です");

#indef _UNICODE
    std::wstring str = c;
#else
    std::wstring wstr = c;
#endif

困った事にUNICODEを判別しないといけません。これをstring系のすべての所に書き分けるのは非常に不便で非効率です。



@ tstring型を作る

 そこでTCHAR型を格納できるtstring型を作ることにします。そのために、std::string及びstd::wstringの宣言部分をちょっと覗いてみます:

typedef basic_string<char, char_traits<char>, allocator<char> > string;
typedef basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t> > wstring;

std::stringやstd::wstringはtypedefされたものである事がわかります。上下の違いはbasic_stringクラスのテンプレートの引数にchar型が渡されているかwchar_t型が渡されているかだけです。よって、

typedef std::basic_string<TCHAR, char_traits<TCHAR>, allocator<TCHAR> > tstring;

とすると、TCHAR型を格納できるtstring型が定義できます。これを使うと、

TCHAR *c = _T("これが何バイト文字かは文字セット次第です");

tstring str = c;

という代入が可能になります。先のtypedefは少し楽ができて、

typedef std::basic_string<TCHAR> tstring;

としてもOKです。basic_stringクラスの第2、第3テンプレート引数を省略するとデフォルトとして第1引数の型が使われます。



A 謝辞

 この記事の内容をご教授下さいましたtkmakwins15さんに感謝申し上げます。