boost::mpl::map не работает boost::mpl::equal?

В документации Boost MPL указано, что boost::map::equal

"Возвращает интегральную константу с истинным значением, если две последовательности Seq1 и Seq2 идентичны при сравнении _element_ по _element_ .

но похоже, что карта ассоциативной последовательности не проверяется на равенство element _wise_:

Следующая демонстрация продемонстрирует это: Map2 должен равняться Map3, которые оба увеличивают значение 'int_‹1>' value_type в 'key'. Посмотрите на typedef, определяющий Map3. Размер и единственный элемент сбрасываются в демо:

#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;
}

Я использую gcc 4.8.1 с Boost 1.51.


person koraxkorakos    schedule 14.08.2013    source источник
comment
Также тег mpl не связан с Boost.MPL. Вам нужен тег boost-mpl. Вы, вероятно, получите ответ от кого-то, кто знает, о чем он / она говорит, если вы добавите его.   -  person llonesmiz    schedule 14.08.2013


Ответы (2)


Причина, по которой он не работает должным образом, заключается в том, что mpl::plus<int_<1>, mpl::at<Map, key>::type — это mpl::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;
person Maxim Egorushkin    schedule 15.08.2013
comment
Вы ответили на другую проблему, которая не связана с его проблемой (этот плюс возвращает тип, отличный от переданного). - person ; 18.03.2014
comment
@GrapschKnutsch Я думаю, вы правы, что порядок элементов в mpl::map не указан, а mpl::equal работает только здесь, потому что обе карты имеют только один элемент. С другой стороны, mpl::equal не определяет какой-либо конкретный порядок сравнений, поэтому он может быть частично специализирован для mpl::map, чтобы он выполнял правильные действия. Хотя я этого не проверял. - person Maxim Egorushkin; 18.03.2014

Результатом вставки элементов в другом порядке в boost::mpl::map являются разные типы, даже если отображение одинаковое. Чтобы обойти эту проблему, вы можете перестроить последовательность, сортируя ее каждый раз, когда вы ее изменяете. Это сильно увеличивает сложность, с которой приходится иметь дело компилятору, особенно если количество записей больше.

person Community    schedule 18.03.2014