すぐ忘れるので,メモ. inline 関数は,先行宣言しておくことで,定義が使用場所より後にある場合でも問題なく使える.
過去記事「テンプレートの部分特殊化を利用した間接参照型推定」では,テンプレートのテンプレートの部分特殊化 (Wikipedia)を使ってポインタ型やイテレータ型からそれを間接参照した型(ポインタを取った型)を推定する方法を紹介した.この方法を使って,例えば和を求めるテンプレート関数の型引数をひとつ減らせられることを示した.しかしこの方法だけだと, const double 型の配列の要素を足し合わせようとしたときコンパイルエラーとなる.これを解決するための,ある型から const を除去した型を推定する方法を紹介する.ここで紹介するテクニックは,高度に抽象化されたテンプレート関数やテンプレートクラスを作るときに必要となる.ついでに, boost C++ ライブラリの remove_const の実装を読んでみよう.…正直,彼ら(boostの実装者たち)は変態さんだと思います.
C/C++ で,エラーを検出してプログラムを強制終了する場合, exit(EXIT_FAILURE) とか abort() を使う.このうち abort() はコアを吐いてから終了してくれるから(linux の場合),コアを gdb などで解析することにより,デバッグが楽になる.例えば gdb a.out core として gdb を起動し, bt コマンドを使えば,バックトレースできる.しかし abort() による終了は穏便ではない.例えば, exit だとグローバルオブジェクトが破棄されるが, abort() だと破棄されない.そこで, success:正常終了, qfail:正常終了(エラーを返す), btfail:正常終了(バックトレースし,エラーを返す), abort:異常終了, df:デフォルト という4+1段階の終了オプションを選択できる終了関数 lexit を定義した.
ちなみにバックトレースとは,プログラムのスタックを表示すること.終了時点での関数から,呼び出しもとの関数を順に main までたどっていく.
C++では, #define で定数を定義するな, const TYPE によるグローバル変数(もしくは適当な名前空間に内包されたグローバル変数)を使え, #define でマクロ関数を定義するな,代わりに inline 関数を使え,みたいなことが言われる.これは確かにその通りだ.
1項 #define ではなく, const と inline を使おう
Scott Meyers (スコット・メイヤーズ): Effective C++ (吉川訳, アスキー出版局, 1998)
に書いてあるように, プリプロセッサよりコンパイラに仕事させるべき だ.でもマクロにしかできないことも多々あるわけで.
適当な構造体 TTest のインスタンスが const で修飾されているとき(const TTest x),そのメンバに値を代入したい,でもそのためだけにそのインスタンス(x)から const を外すのは嫌,という場合を考えよう.あるいは const メンバ関数(メンバ変数を変更しないメンバ関数)で,テンポラリなメンバ変数を変更したい,でもそのメンバ関数を非 const にするのは嫌,という場合でもいい.結論から言えば, mutable を使うと解決できる.
メモリの二重解放とは, new などで確保したメモリ領域(ヒープ領域)を2回 delete などで解放することを言う. new と delete をきちんと対応させて書いていないときに起こる問題だ.特にクラスのメンバに動的確保したメモリへのポインタを含む場合にやってしまいがちである.ここでは二重解放によって発生する問題を解説する.
戻り値が void 型である関数 func1 を,戻り値が void 型であるほかの関数 func2 において,
return func1(..);
のように返せるか実験してみた.
先日,LaTeX の数式を PNG と SVG に変換する方法についての記事を載せた.この方法を使いやすくスクリプト化してみた.
liboctave 利用時のコンパイルを「遅い」と感じたことはないだろうか.ここでは liboctave におけるヘッダファイルの依存関係を把握することにより,コンパイルを高速化する方法を検討する.
C++の機能,テンプレートの部分特殊化 (Wikipedia)を使って,あるポインタ型orイテレータ型から,それを間接参照した(or逆参照した,orポインタをとっぱらった)型を推定する方法を紹介する.
bash で2次元配列を扱いたいときがまれにある.が, bash には1次元配列しか無いし,配列の要素に配列を代入することもできない.そこで疑似的に2次元配列を使う方法を考えてみた.
デフォルトパラメータを持つ仮想関数を継承する場合の振る舞いを調べてみた.仮想関数は「動的に結合」される一方,デフォルトパラメータは「静的に結合」される.
C/C++ で配列の各要素に名前をつける方法について.例えば,
unsigned char col[4];
として宣言された col の各要素を red, green, blue, alpha のような識別子でも参照できるようにする.
STL (標準テンプレートライブラリ) の std::vector とか liboctave の ColumnVector,あるいは普通の配列に対して共通に使えるテンプレート関数の作り方を説明する.
C++ で実装した関数を C から利用したい場合,あるいはその逆の場合がある.同じソースの中に両方のプログラムコードを書くことはできないが,それぞれのソースをコンパイルしてオブジェクトファイルを生成し,それらをリンクすることは可能だ.ただし C++ 特有の名前空間 (namespace) や関数オーバーロードに対処する必要がある.
linux で,リンク先のファイルが存在しないシンボリックリンクを一覧するスクリプト.
ふと気になって,C++のプリプロセッサ・ディレクティブ (Preprocessing directives) を調べてみた.ソースは ISO/IEC 14882:1998 (E).gcc/g++ で何気なく使っていた #warning は標準じゃないことを知った.
Gnuplot (4.2.4) は,ライセンスの関係がどうとかで readline がデフォルトでは使えない.このためコマンドプロンプト上でファイルを Tab キーとかで補完できないので不便だ.そこで自分でコンパイルする.
iomanip の setw(5) みたいなノリで,出力する文字に色をつける方法を考える.
cout<<ioscc::green<<"GREEN"<<endl;
のようにすれば,緑色で GREEN が表示されるようにしたい. std::endl で色がリセットされる.
似たような話題は検索すればいくらでも見つかる.が,イマイチなのが多い(ような気がする).ここでは日本語とかも出力できる方法を解説する.かなり力技なので環境依存性が強いかも.