2013-06-30 53 views
2

消失下面的例子說明我的意思:插入項目從boost :: MPL ::地圖

#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::type我插入消失的項目評估update2

爲什麼會發生這種情況,我該怎麼做以確保評估update2不會刪除插入的元素?

回答

2

我確信這是一個在boost::mpl中的錯誤。

將元素插入到mpl::map中的結果不是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_item,然而,缺乏這種typedef等,因爲它從它插入m_item::typemap派生實際上是map::type

這意味着插入後我的例子(丟棄int_<>爲了簡潔)的樣子:

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

和訪問它的類型達到一路回升到map1<pair<1, 1> >::type返回map<pair<1, 1> >這就是爲什麼所有插入的項目消失。

我登錄了一個bug,最初在發佈這個答案之前等待回覆,但在4周後我決定發佈這個沒有任何答案。

解決方法是在boost/mpl/map/aux_/item.hpp中簡單地將typedef m_item type;添加到boost::mpl::m_item。這將使m_item成爲正確返回自身並且不返回原始映射的元函數。