シイラアサン様萌えなのですよ?
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でないということ).
ところがMSVCはデフォルトでwchar_tがunsigned shortの単なるtypedefであり,標準に準拠した仕様ではない.このままだとwchar_tが識別可能な型であることに依存したコードで不都合が生じる.MSVCでは,このwchar_tの非標準な性質を避けるためのコンパイラオプションを持っていて,/Zc:wchar_tを指定することで設定できる.
3.9.1 Fundamental types5 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.
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が識別可能な型であるかどうかを判定するポータブルな方法として,
てーか,user-config.jamあたりにtoolsetのconfigurationのデフォルトを指定するようなやり方はないのかにゃ?
#user-config.jamはユーザ環境の指定だから,そっちにプロジェクトが必要とするコンパイルスイッチの指定を入れるべきじゃないか.
project-root.jam + Jamfile = Jamroot
いつの間にかproject-root.jamがルートにおけるJamfileの役割を吸収して,Jamrootという1つのファイルで代替可能なようになってるにゃー.
Boost.Build v2でBoost引っ張ってくる設定簡単にしたいにゃー
てか,Boost.Buile v2でBoost引っ張ってくる設定毎回書くの面倒くさいにゃー.site-config.jamかuser-config.jamにまとめられないかにゃー.
import modules ; import path ; local boost-build-path = [ modules.peek : BOOST_BUILD_PATH ] ; local boost-root = [ modules.peek : BOOST_ROOT ] ; boost-root ?= $(boost-build-path[2])/../../.. ; boost-root = [ path.make $(boost-root) ] ; path-constant BOOST_ROOT : $(boost-root) ; use-project /boost : $(BOOST_ROOT) ;
BOOST_BUILD_PATHかBOOST_ROOTという環境変数さえ設定していれば後はよろしくやってくれます的設定.後はincludeパスはprojectの設定かどっかで
project my-project : requirements <include>$(BOOST_ROOT) ;
で,ライブラリは
run test.cpp /boost/test//boost_unit_test_framework ;
な感じで引っ張ってこれます的設定.
そうだ,Boost.Build v2を広めよう
てか,Boost.Build普及のために自分が知ってるBoost.Buildの知識ぶべべべべっと吐き出した方が良いような気がしてきた.