lexical_castとワイド文字(wchar_t)とVisual C++と

boost::lexical_castがMSVCのwchar_tに対して機能しなくて,なんでかな〜と思って原因調べたらwchar_tが固有の型であることを要求していることが判明(BOOST_NO_INTRINSIC_WCHAR_Tを見て,固有でないならワイド文字の実装を切ってる).IDE上のビルドで上手くいってコマンドライン上のビルドだとこけるという不可解な挙動だったけれど,IDE上のビルドのときに癖で「wchar_tをビルトイン型として扱う」にチェックを入れてたせいでしたとさ.まる.

説明

wchar_tは規格上は他の型と識別可能な型でないといけない(他の型と識別できるというのは,「その型独自のテンプレートの特殊化ができる」あるいは「その型独自の関数オーバーロードが可能である」と定義できる.要するに他の型の(weak) typedefでないということ).


3.9.1 Fundamental types

5 Type wchar_t is a distinct type whose values can represent distinct codes for all members of the largest extended character set specified among the supported locales (22.1.1). Type wchar_t shall have the same size, signedness, and alignment requirements (3.9) as one of the other integral types, called its underlying type.

ところがMSVCはデフォルトでwchar_tがunsigned shortの単なるtypedefであり,標準に準拠した仕様ではない.このままだとwchar_tが識別可能な型であることに依存したコードで不都合が生じる.MSVCでは,このwchar_tの非標準な性質を避けるためのコンパイラオプションを持っていて,/Zc:wchar_tを指定することで設定できる.
IDE上で設定するときは,プロジェクトのプロパティ -> C/C++ -> 言語 -> wchar_tをビルトイン型として扱う -> はい (/Zc:wchar_t) で設定.
Boost.Build v2で設定するときには条件付feature指定をtargetのrequirementsに指定してしまうか,

exe my-exe
  : my.cpp
  : <toolset>msvc:<cxxflags>"/Zc:wchar_t /Zc:forScope"
  ;

もしくはprojectのrequirmentsに指定してしまって,プロジェクト下の全てのビルドに指定してしまうか.

project my-project
  : requirements
    # 他のrequirements
    <toolset>msvc:<cxxflags>"/Zc:wchar_t /Zc:forScope"
  ;

上で指定している/Zc:forScopeも自分の癖.
ちなみに手持ちのコンパイラにおいてwchar_tが識別可能な型であるかどうかを判定するポータブルな方法として,で提供されるBOOST_NO_INTRINSIC_WCHAR_Tが使える.
てーか,user-config.jamあたりにtoolsetのconfigurationのデフォルトを指定するようなやり方はないのかにゃ?
#user-config.jamはユーザ環境の指定だから,そっちにプロジェクトが必要とするコンパイルスイッチの指定を入れるべきじゃないか.