読者です 読者をやめる 読者になる 読者になる

boost::optionalを使って、Nullableなイテレータを実装する

boost::optionalは通常の値に「無効値」を加える仕掛け。
関数などの戻り値でNULLとか0とか-1を「無効値」と扱うケースがあるけど、そうはいかない場合に有効。 あるいは、STLコンテナの「どこも指していない」イテレータが欲しい場合とか。

//---------------------------------------------------------------------------
#include <vector>
#include <boost/optional.hpp>
#include <iostream>
#pragma hdrstop

#include <tchar.h>
//---------------------------------------------------------------------------

#pragma argsused
int _tmain(int argc, _TCHAR* argv[])
{
    boost::optional<std::vector<int>::iterator> nullable_iter;
    std::vector<int> vv;

    vv.push_back(10);
    vv.push_back(20);
    vv.push_back(30);
    vv.push_back(40);
    vv.push_back(50);

    // iterは「有効値」か否かチェック
    if (nullable_iter) {
        std::cout << "iter is not none" << std::endl;
    } else {
        std::cout << "iter is none" << std::endl;
    }

    nullable_iter = vv.begin();
    if (nullable_iter) {
        std::cout << "iter is not none" << std::endl;
        std::vector<int>::iterator iter = *nullable_iter;   // optionalの「中身」へは「*」でアクセス

        // この例ではoptionalの「中身」はイテレータなので、「**」で値にアクセス
        std::cout << "value is " << **nullable_iter << std::endl;
    } else {
        std::cout << "iter is none" << std::endl;
    }

    // 「無効値」にする
    nullable_iter = boost::none;

    return 0;
}
//---------------------------------------------------------------------------

「無効値」そのものは、boost::none。個人的には、C++0xで導入されるnullptrがコンテナでも「無効値」と見なしてくれれば、もうちょっとエレガントになりそうな気が。