下面的例子演示了我的意思:
#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
不会删除插入的元素?
我确信这是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
,因此,由于它是从map
派生出来的,所以它被插入到m_item::type
中实际上是map::type
。
这意味着插入后的示例(为了简洁起见,去掉int_<>
)看起来像:
m_item<5, 5, m_item<4, 4, map1<pair<1, 1> > > >
并且访问其类型一直回到返回CCD_ 19的CCD_。
我记录了一个错误,最初是在发布这个答案之前等待回应,但4周后,我决定在没有他们任何答案的情况下发布这个。
解决方案是简单地将typedef m_item type;
添加到boost/mpl/map/aux_/item.hpp
中的boost::mpl::m_item
。这将使m_item
成为一个正确返回自身而不返回原始映射的元函数。