サンプルの動作確認バージョン [GCC4.4/1.41.0] [VC9/1.41.0]
#include <iostream>
#include <string>
#include <boost/utility/value_init.hpp>
using namespace std;
int main()
{
int x;
cout << x << endl;
boost::value_initialized<int> y;
cout << y << endl; // or cout << y.data() << endl
string s;
cout << s.size() << endl;
boost::value_initialized<string> t;
cout << t.data().size() << endl;
return 0;
}
4284456 0 0 0
※ 不定値を表示する実験 cout << x << endl;
は、
実行環境のバグ検知機能でバグとして検出されてしまうことがあります。
Visual C++ の場合、上のような実行結果を見るには、
/RTC オプション
をオフにしてコンパイルして下さい。
ユーザー定義したクラスなどの値を、何も引数無しで宣言すると、デフォルトコンストラクタによる初期化が行われます。これに対して、intなどの組込型や、コンストラクタの定義されていないPOD型を引数無しで宣言すると、何も初期化は行われず不定値になります。
int x; // 不定
string s; // stringクラスのデフォルトコンストラクタが呼ばれる
組込型を既定値(intなら0、floatなら0.0、ポインタならNULLなど)に初期化するには、 こんな風に書く必要があります。
int x = int(); // 既定値での初期化
ところがこの前者の書き方をコンストラクタ付きのクラスで使うと…
string s = string(); // ?
場合によっては期待通りに動作しますが、環境やクラスの実装によっては、 デフォルト初期化でなくコピーコンストラクタやその他他のコンストラクタの 呼び出しが生じてしまうことがあります。というわけで、template<typename T> 関数の中で、「T型の既定値に初期化された値」が欲しいと思ったら、 汎用性のある書き方が無くて困ってしまいます。そこで、 この「T型の既定値に初期化された値」を提供するのが、この value_initialized です。 使用機会は限られると思いますが、 存在を覚えておいて損はないコンポーネントでしょう。ちなみに実装は、
class SomeClass {
int x;
SomeClass() : x() {}
};
この記法ならば int でも string でも共通で既定値初期化が行えることを利用して組まれています。