beyond the Modern C++ Design

Modern C++ Design―ジェネリック・プログラミングおよびデザイン・パターンを利用するための究極のテンプレート活用術 (C++ In‐Depth Series)
C++ Template Metaprogramming: Concepts, Tools, and Techniques from Boost and Beyond (C++ In-Depth Series)

C++のtemplateについて古典と言えば『Modern C++ Design』であって、「これを読まずしてtemplateを語ることなかれ」というぐらいバイブル的な本だ。(とは言うものの、実際のところこんなに変態的なtemplate駆使したプログラムを書かれても保守が大変で困るんだが・・) 英語が苦でなければ『C++ Template Metaprogramming』もお勧めする。


それはともかく。現代の視点で『Modern C++ Design』を読み直すと、「おや?」と思うことが多い。例えば、コンパイル時の表明。*1


#define STATIC_CHECK(expr) { char unnamed[(expr) ? 1 : 0]; }

「長さ0の配列が不正なものと扱われる」ことを利用している。しかし、gccでは警告だけでコンパイルエラーにはならない。これは、C/C++の規約上はそこまで規定されていないのだろうか?少なくとも(gccコンパイルエラーにならないという)現実的な観点から、0ではなく-1(負数)にするべきだと思う。


しかし、これで安泰とは言えない。id:Robeさん*2に上のコードだと式として評価されないのでまずいのではないかと教えてもらった。ロベールさんの示したコードは次のものだ。


#define SASSERT(b) ((void)(int(*)[(b) ? 1 : -1])0)


実際、マクロのなかで表明しようと思ったとき、static assertが式として扱われなくては困る。(例:id:Robe:20060721の2進リテラルのコード)


いろいろ勉強させられた。このように現代の視点で過去の技術をいま一度見直してみると面白いかも知れない。

・現代の視点によるOOP
・現代の視点によるデザインパターン
・現在の視点によるgotoプログラミング
・現代の視点による・・・

*1:『Modern C++ Design』にはC++のtemplateで書かれたコンパイル時の表明を行なうものも書かれているが、C言語も対象としたいので、今回の議論では割愛することにする。

*2:C++講座で有名なロベールの部屋のロベールさんがはてなユーザーになった!