2

次の例は、私が何を意味するかを示しています。

    #include <boost/mpl/map.hpp>
    #include <boost/mpl/for_each.hpp>
    #include <boost/mpl/pair.hpp>
    #include <boost/mpl/at.hpp>
    #include <boost/mpl/insert.hpp>
    #include <iostream>

    using namespace boost::mpl;

    template <int n1, int n2>
    struct entry
    {
        typedef pair<int_<n1>, int_<n2> > type;
    };

    typedef map<entry<1,1>::type> entries;

    typedef insert<
        entries, entry<4,4>::type>::type update;

    typedef insert<
        update,
        entry<5,5>::type>::type update2;

    struct print_values
    {
        template <class I>
        void operator()(I)
        {
            std::cout << first<I>::type::value << ", " 
                      << second<I>::type::value << std::endl;
        }
    };

    int main()
    {
        for_each<update2>(print_values());
        std::cout << "Next:" << std::endl;
        for_each<update2::type>(print_values());
    }

出力:

    1, 1
    4, 4
    5, 5
    Next:
    1, 1

update2挿入したアイテムにアクセスして評価するupdate2::typeと消えます。

なぜこれが起こるのですか? また、評価update2によって挿入された要素が削除されないようにするにはどうすればよいですか?

4

1 に答える 1

2

これは のバグだと確信していboost::mplます。

要素を an に挿入した結果はmpl::map、 type の項目ではなく、 の項目mpl::mapですmpl::m_item。これm_itemは、新しく挿入されたキーと値、およびそれらが挿入されたマップを保持します。
現在、すべてのクラスboost::mplはメタ関数であり、コンテナは自分自身を返すメタ関数です。こんな場面で重宝します

    typedef map<pair<int,int> > i_map;
    eval_if<true_,
            i_map,
            at<i_map, float> >::type type;

そのため、単純に ,mpl::mapである typedef が内部にありますが、これが欠けているため、実際には に挿入されているから派生しているためです。typedef map type;m_itemtypedefmapm_item::typemap::type

これは、挿入後の例 (int_<>簡潔にするために を削除) が次のようになることを意味します。

   m_item<5, 5, m_item<4, 4, map1<pair<1, 1> > > >

そのタイプにアクセスすると、map1<pair<1, 1> >::typeどのリターンまで戻るかが返されますmap<pair<1, 1> >。これが、挿入されたすべてのアイテムが消えている理由です。

私はバグを記録し、最初はこの回答を投稿する前に回答を待っていましたが、4週間後、彼らからの回答なしにこれを投稿することにしました.

解決策は、単純にin に追加するtypedef m_item type;ことです。これにより、自分自身を正しく返し、元のマップを返さないメタ関数が作成されます。boost::mpl::m_itemboost/mpl/map/aux_/item.hppm_item

于 2013-07-26T11:50:47.480 に答える