c++boost.gif (8819 bytes)HomeLibrariesPeopleFAQMore

Frequently Asked Questions

1. void ポインタを見かけたが、こいつはタイプセーフなのか?
2. 何故 void の return の回避手段を取っているのか? C++ では許されているはずだ!
3. 何故 (関数を) コピーするのか?
1.

void ポインタを見かけたが、こいつはタイプセーフなのか?

はい。 boost::function は void ポインタや、戻り値も引数もない関数ポインタを使っているが、タイプセーフだ。関数ポインタや関数オブジェクトを管理/実行する関数の中には、全ての型の情報が書き込まれている。 void ポインタや void 関数ポインタが指す本当の型を知らされてインスタンス化されるのは、これらの管理/実行用関数だけなのだ。 void ポインタと void 関数ポインタの両方が必要な理由は、オブジェクトへのポインタと void ポインタは互いに安全にキャストでき、異なる型の関数ポインタ同士も安全にキャストできる事だ (ただし、異なる型で関数ポインタを呼び出してはならない) 。

2.

何故 void の return の回避手段を取っているのか? C++ では許されているはずだ!

void の return は C++ 標準で許されている。以下はこれを使ったコードの一部だ。

void f();
void g() { return f(); }

void の return を使わない理由の 1 つとして、全てのコンパイラが void の return をサポートしているわけではない事が挙げられる。実際には、このちょっとした機能をサポートするコンパイラは極一部だ。さらに、 void の return を使わない事で、 boost::function はもっと柔軟になった。以下の例を考えてみよう。[訳注1]

int do_something(int);

boost::function<void, int> f;
f = do_something;

この boost::function の使い方が有効なのは、 void の return が使われていないからだ。 void の return を使うと、以下のコードと同等の不正なコードをコンパイルしようとする事になる。

int f();
void g() { return f(); }

void の return を使わない事で、 boost::function は戻り値を飲み込めるようになる、というのが本質なのだ。この事は、「ぴったり一致しないパラメータを持つ関数や関数オブジェクトを代入/実行できる」事とも一貫している。

3.

何故 (関数を) コピーするのか?

2000 年の 11 〜 12 月に、コピー vs. 参照の論争が長々と繰り広げられた。その結果、コピーの方が予測しやすいセマンティクスになるという結論になった。私はここでその議論を蒸し返すつもりはない。コピーが不適当な場合は、参照カウント式アロケータを使えばよい。

[訳注1] この段落とその次のコードは Ver.1.30 の原文から抜けていた。ミスと思われるので、 Ver.1.29 を元にして補完しておいた。

Last revised: February 19, 2003 at 22:46:09 GMTCopyright © 2001-2003 Douglas Gregor