2003-12-25

たまには C++ の話を.

気晴らしに.

C++ のライブラリについては, boost がおおよその物事を解決しそうな気配が見える. GUI や OS のサービスなど解決しない問題も本当は多い. けれど, C++ はもうそれについて解決する気がなさそう. この言語の良いところはそれが役に立たないところで, この言語の悪いところはそれが役にたつところだ. というのはレトリックだけれど, そういうところで中途半端に役に立とうとしない boost の姿勢からは C++ 利用者の総意を感じる.

C++ 言語仕様は相変らずどうしようもない. 諸悪の根源(のひとつ)が C 由来のポインタであることを Microsoft はよくわかっていて. 彼らはそれを改善しようとしている.

ハンドルとハット

次バージョン(次々バージョン?) の VisualStudio で, Microsoft は C++ を大きく拡張する. 現在ぎこちなく繋っている native C++ の世界と managed C++ の世界(.NET/CLI の世界) をシームレスに繋ぐための拡張. それをハンドルという.

現在の VC++ では __xx というようなベンダ依存の修飾をつけることで, あるポインタを "これは .NET 世界のポインタですよ" と宣言する. これはわかりにくいし, あいかわらずポインタだ. ハンドルは違う. ハンドルはポインタと似ているがポインタ(=生の番地情報)ではなく, Java の参照のみたいなものだ. だから *p というように dereference することはもちろんできないし, p++ みたいなポインタ演算もできない. 非常に限定されている. かわりにガベージ・コレクションの対象になる.

Microsoft の大きな決断は, ハンドルを表わすのにアンダースコアによるベンダ拡張ではなく, 独自の文法, 演算子を定義したことだ. ハンドルは次のように宣言する.

Button ^ b;

b = gcnew Button;

"^" がハンドルをあらわす演算子. gcnew は managed なオブジェクトを生成するためのキーワードになる. "^" は見事な選択だと思う. これをオーバーロードする人はそういないだろう (...と思ったら spirit はオーバーロードしていた.) とにかく, Microsoft は C++ の文法を拡張することで managed の世界と native の世界をうまく繋いだ. 重要なのはこの文法のもつ自然さにある. 機能的には アンダースコア装飾とそう差はないけれど, 心理的な障壁はおおきく違う. "^" は Microsoft 依存に躊躇する開発者の背中を押してくれる. ぽん.

当初は CLI のオブジェクトだけが gcnew で確保できる. 将来的には, native のオブジェクトを gcnew で確保すること(あるいはその逆)ができるようになるらしい. STL と .NET を混在させるようになるんだろうか. おそろしい. スタックの上はどうなるんだろう. ただでさえ例外処理やカナリアで騒々しいのに...

なお, こういった話題は Microsoft 運営のコミュニティサイト GOTDOTNET にある Brandon Bray の weblog や, その BLOGROLL (というのはリンク集のことらしい) から辿ることができる. C++ マニアには面白い話題だが分量も多い. 正月の暇潰しに読むにはよいかもしれない.

コンセプト

Microsoft の拡張が彼らの都合に合わせた独自路線なのに対し, guru of C++ である BS が提案する C++ 拡張は我ら不毛の民の心を代弁している. boost の concept_check ライブラリを思いだそう. これは テンプレート引数の要件 = コンセプト を手続的に記述するライブラリだ. このアイデアを言語仕様としてとりこもうと BS は提案する. 目的は template の繰り出すエラーメッセージの爆発からプログラマを救うこと. ISO C++ WG のページ にある "Concepts - Design choices for template argument checking" に概要がまとまっている. (関連資料も同じページにある. このページの文書群もまた C++ マニアの正月用テキストになりそう.) アイデアはまとまりきっていないようだが, おおよそ次のように書けるらしい.

concept Comparable {

constraints( Comparable a, Comparable b ) {

a == b; a != b; a == 1; a != 1; before(a,b); after(a,b);

}

};

template <Comparable C> class T {

.....;

};

割と妥当なかんじ. しかし C++ にはこういう直観が通用しないから, 色々叩かれ修正されていくだろう. これが標準化, 実装されるのは今世紀の終わりくらいかな...という気がしてしまう. でも夢はあるね. BJ は "実装は難しいけど, concept をある種の class として扱えばまあなんとかなる" みたいなことをいっている. ほんとかよ...

C++ が複雑さの袋小路にはまりこんでいく様は, 外から眺める分には面白い. 彼らはどこに向かうのだろう. それを見届けたい気はする.