boost::mpl::map失败了,boost::mpl::equal也失败了?

4
Boost MPL文档指出boost::map::equal,如果按元素逐个比较,两个序列Seq1和Seq2相同时返回一个真值积分常量。但是似乎关联序列的map未被逐个元素地检查是否相等。下面的示例将说明这一点:Map2应该等于Map3,它们都会增加'key'处'int_<1>'value_type的值。请查看定义Map3的typedef。大小和唯一元素在演示中被转储。
#include<iostream>
#include<boost/mpl/map.hpp>
#include<boost/mpl/at.hpp>
#include<boost/mpl/insert.hpp>
#include<boost/mpl/erase_key.hpp>
#include<boost/mpl/pair.hpp>
#include<boost/mpl/int.hpp>
#include<boost/mpl/plus.hpp>
#include<boost/mpl/equal.hpp>
#include<boost/mpl/size.hpp>
#include<boost/mpl/front.hpp>

namespace mpl = boost::mpl;
using mpl::int_;

using std::cout;
using std::endl;
using std::is_same;

int main(int argc, char *argv[])
{

    typedef int key;

    typedef typename mpl::map<mpl::pair<key, int_<1>>> Map;
    typedef typename mpl::map<mpl::pair<key, int_<2>>> Map2;

    typedef typename mpl::insert<
    typename mpl::erase_key<Map,
                            key>::type, 
        mpl::pair<key, 
                  typename mpl::plus<int_<1>, 
                                     typename mpl::at<Map, key>::type>::type
        >::type
    >::type Map3;

    cout << "equal? " << mpl::equal<Map2,Map3>::type::value << endl;
    cout << "size? " << mpl::size<Map3>::value << endl;
    cout << "key type at front? " << typeid(mpl::front<Map3>::type::first).name() << endl;
    cout << "value type at front? " << mpl::front<Map3>::type::second::value << endl;

    cout << "expected size? " << mpl::size<Map2>::value << endl;
    cout << "expected key type at front? " << typeid(mpl::front<Map2>::type::first).name() << endl;
    cout << "expected value type at front? " << mpl::front<Map2>::type::second::value << endl;

    return 0;
}

我正在使用带有Boost 1.51的gcc 4.8.1。


1
另外,[tag:mpl] 标签与 Boost.MPL 无关。你需要的标签是 [tag:boost-mpl]。如果你添加它,很可能会得到一个知道自己在说什么的人的答案。 - llonesmiz
2个回答

3

它不能像预期的那样工作的原因是mpl::plus<int_<1>, mpl::at<Map, key>::typempl::integral_constant<int, 2>,然而mpl::int_<2>是不同的类型。

一个可行的版本:

typedef mpl::map<mpl::pair<key, mpl::integral_c<int, 1>>> Map;
typedef mpl::map<mpl::pair<key, mpl::integral_c<int, 2>>> Map2;

typedef mpl::insert<
    mpl::erase_key<Map, key>::type,
    mpl::pair<key, mpl::plus<mpl::integral_c<int, 1>, mpl::at<Map, key>::type>::type>
>::type Map3;

你回答了另一个问题,这只是他问题的附属问题(加号返回的类型与传递的不同)。 - user678269
@GrapschKnutsch我认为您是正确的,即mpl :: map中元素的顺序是未指定的,并且mpl :: equal之所以有效只是因为两个映射都仅有一个元素。另一方面,mpl :: equal没有指定任何特定的比较顺序,因此它可以部分专门化为mpl :: map以执行正确的操作。不过我并没有验证。 - Maxim Egorushkin

2
将元素以不同的顺序插入到boost::mpl::map中,将得到不同的类型——即使映射是相同的。为了解决这个问题,您可以通过在每次修改时对序列进行排序来重建它。这会大大增加编译器需要处理的复杂性,特别是当条目数量较多时。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接