C++と色々

主にC++やプログラムに関する記事を投稿します。

boost::optional

夏休み中サボってしまった… マイペースで行こう()
あ、自分のプログラムに関する理解が誤っているの気づいた方はコメントで突っ込んで頂けると嬉しいです…

今回はboost::optionalを試してみよう
boost::optionalは、T型に無効値を追加した型みたいなもの。

C/C++において関数の戻り値で不正な値やエラーを表すとき、整数値(-1とか0とか1)とか、NULLマクロ(実質0)とか、例外、nullptr(C++のみ)とか関数ごとに表現方法がバラバラだった。
boost::optionalを使うとそれらの表現を統一することができる。使い方は生ポインタのように使えるように作られている。
サンプル

#include <iostream>
#include <boost/optional.hpp>

//T型の配列arrayにtargetがあったらその値を、見つからなければ無効値を返す
template<class T>
boost::optional<T> search(T array[], std::size_t array_size, T target)
{
	for(std::size_t i = 0; i < array_size; i++)
	{
		if(array[i] == target)
		{
			return array[i];
		}
	}

	return boost::none;//無効値
}

int main()
{
	int array[] = {1, 2, 3, 10, 20, 30};

	//見つかる場合
	if(const auto op = search(array, 6, 10))
	{
		std::cout << "found : " << *op << std::endl;
	}
	else
	{
		std::cout << "not found." << std::endl;
	}

	//見つからない場合
	if(const auto op = search(array, 6, 999))
	{
		std::cout << "found : " << *op << std::endl;
	}
	else
	{
		std::cout << "not found." << std::endl;
	}
}

実行結果

found : 1
not found.
続行するには何かキーを押してください . . .

main関数を見ると生ポインタと同じように使えるように見える。
boost::optionalは普通のその方の変数のように代入できるし、間接参照演算子を用いて値を得ることもできる。
ポインタと違うところもあって、boost::optionalの値を変更しても、元の変数の値は変更されない

int a = 10;
boost::optional b = a;//OK
std::cout << *b << std::endl;//OK
b = 20;//bは20
std::cout << a << std::endl;//aは10のまま

しかしboost::optionalとすることで、boost::optionalの値を変更した場合、元の変数の値に影響が出る。
ほとんど生ポインタと同じ挙動をすることができる。何も参照しない時はnullptrの代わりにboost::noneを代入すればいい。
しかも生ポインタよりも安全に使うことができる。(deleteできない、必ずboost::noneで初期化される、等々…)

調べると、関数の戻り値ばかりでなく、変数のスコープ管理やループ処理にも有効なようだけど、もう少し時間を掛けて勉強しよう…

下記の参考サイトのほうが正確で詳しいです

参考文献
"それでも Boost.Optional を使う、大きく分けて2つくらいの理由":http://d.hatena.ne.jp/gintenlabo/20100606/1275854791(2012/9/27アクセス)