以下示例演示了我的意思:
#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
不会删除插入的元素?
答案 0 :(得分: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
,因为它来自map
它插入到m_item::type
实际上是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周之后我决定发布此答案而没有任何答案。
解决方案是在typedef m_item type;
中简单地将boost::mpl::m_item
添加到boost/mpl/map/aux_/item.hpp
。这将使m_item
元函数正确返回自身而不返回原始地图。