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

vector<optional<T>>に対するindirected

C++

Use boost::optional together with boost::adaptors::indirected


vector>に対してindirectedするとコンパイルエラーになる問題があるようです。
indirect_iterator内部では、boost::pointeeメタ関数を使用してポインタと見なせる型から内部の型を取り出しているので、optionalで特殊化すれば使えるようになります。

#include <boost/optional/optional_fwd.hpp>
#include <boost/pointee.hpp>
#include <boost/mpl/identity.hpp>

namespace boost {
    template <class T>
    struct pointee<optional<T>> : mpl::identity<T> {};
};

#include <iostream>
#include <vector>
#include <boost/optional.hpp>
#include <boost/bind.hpp>
#include <boost/range/adaptor/filtered.hpp>
#include <boost/range/adaptor/indirected.hpp>
#include <boost/range/algorithm/for_each.hpp>

void disp(int x) { std::cout << x << ' '; }

int main()
{
    // 要素が全部入ってる場合
    {
        std::vector<boost::optional<int>> v = { 1, 2, 3 };
        boost::for_each(v | boost::adaptors::indirected, disp);
    }
    std::cout << std::endl;

    // 入ってない要素がある場合
    {
        using namespace boost::adaptors;

        std::vector<boost::optional<int>> v = { 1, boost::optional<int>(), 3 };

        boost::for_each(
            v | filtered(boost::bind(&boost::optional<int>::is_initialized, _1)) | indirected,
            disp);
    }
}
1 2 3 
1 3 

これはまぁ、そのうちBoost側に修正が入るでしょう。