boost::map дубликаты ключей
От: Warturtle  
Дата: 22.07.15 18:17
Оценка: -1
Всем привет! Коллеги, объясните пожалуйста по возможности такое поведение:
#include "boost/static_assert.hpp"
#include "boost/mpl/map.hpp"
#include "boost/mpl/insert.hpp"
#include "boost/mpl/size.hpp"

namespace mpl = ::boost::mpl;

int main()
{
    struct A {};
    struct B {};
    struct C {};
    struct string {};

    typedef mpl::map< 
        mpl::pair< A, int > 
        , mpl::pair< B, char > 
        , mpl::pair< C, string > 
    >
    ::type m1;

    typedef mpl::insert< m1, mpl::pair< A, int > >::type m2;
    typedef mpl::insert< m1, mpl::pair< A, double > >::type m3;

    BOOST_STATIC_ASSERT( mpl::size< m2 >::value == mpl::size< m1 >::value );
    BOOST_STATIC_ASSERT( mpl::size< m3 >::value == mpl::size< m1 >::value + 1 );
}

— почему при вставке имеющейся пары (совпадают оба два элемента) добавления не происходит, а при вставке с другим значением (совпадают только ключи) — происходит? Версия буста 1.49. Спасибо за внимание.
Re: boost::map дубликаты ключей
От: Warturtle  
Дата: 23.07.15 07:20
Оценка:
Здравствуйте, Warturtle, Вы писали:

W>Всем привет! Коллеги, объясните пожалуйста по возможности такое поведение:

W>...
W>- почему при вставке имеющейся пары (совпадают оба два элемента) добавления не происходит, а при вставке с другим значением (совпадают только ключи) — происходит? Версия буста 1.49. Спасибо за внимание.

Оценки — это прекрасно, а по существу вопроса уважаемые господа что скажут? Ну, кроме RTFM — видимо я тупой и не понял чего-то из документации. Так и должно быть или где? А если должно, то почему?
Re[2]: boost::map дубликаты ключей
От: jazzer Россия Skype: enerjazzer
Дата: 23.07.15 07:49
Оценка: -1
Здравствуйте, Warturtle, Вы писали:

W>Оценки — это прекрасно, а по существу вопроса уважаемые господа что скажут? Ну, кроме RTFM — видимо я тупой и не понял чего-то из документации. Так и должно быть или где? А если должно, то почему?


Попробуй проделать то же самое с std::map, или с питоновским dict, или с перловским hash, и помедитируй над результатом
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[3]: boost::map дубликаты ключей
От: Warturtle  
Дата: 23.07.15 11:24
Оценка:
Здравствуйте, jazzer, Вы писали:

J>Здравствуйте, Warturtle, Вы писали:


W>>Оценки — это прекрасно, а по существу вопроса уважаемые господа что скажут? Ну, кроме RTFM — видимо я тупой и не понял чего-то из документации. Так и должно быть или где? А если должно, то почему?


J>Попробуй проделать то же самое с std::map, или с питоновским dict, или с перловским hash, и помедитируй над результатом

Нет я правда не понимаю, что ты имеешь ввиду:
#include <stdio.h>
#include <map>

typedef std::map< int, int > Map;
void Print(Map const & m)
{
    for (Map::const_iterator i = m.begin(); i != m.end(); ++i)
        ::printf("(%d, %d)\n", i->first, i->second);
}
int main()
{
    ::printf("1.\n");
    Map m;
    m.insert( std::make_pair(1, 10) );
    m.insert( std::make_pair(2, 20) );
    m.insert( std::make_pair(3, 30) );
    Print(m);
    ::printf("2.\n");
    m.insert( std::make_pair(1, 10) );
    Print(m);
    ::printf("3.\n");
    m.insert( std::make_pair(1, 555) );
    Print(m);
}

не добавляется и не должен. Мало медитировал или что?
Re[3]: boost::map дубликаты ключей
От: Warturtle  
Дата: 23.07.15 11:29
Оценка:
Здравствуйте, jazzer, Вы писали:

J>Здравствуйте, Warturtle, Вы писали:


W>>Оценки — это прекрасно, а по существу вопроса уважаемые господа что скажут? Ну, кроме RTFM — видимо я тупой и не понял чего-то из документации. Так и должно быть или где? А если должно, то почему?


J>Попробуй проделать то же самое с std::map, или с питоновским dict, или с перловским hash, и помедитируй над результатом

Может я недостаточно ясно сформулировал вопрос, тогда замечу еще, что в первом сообщении у меня не срабатывают оба ассерта, т.е. программа компилится.
Re[3]: boost::map дубликаты ключей
От: Warturtle  
Дата: 23.07.15 11:52
Оценка:
Здравствуйте, jazzer, Вы писали:

J>Здравствуйте, Warturtle, Вы писали:


W>>Оценки — это прекрасно, а по существу вопроса уважаемые господа что скажут? Ну, кроме RTFM — видимо я тупой и не понял чего-то из документации. Так и должно быть или где? А если должно, то почему?


J>Попробуй проделать то же самое с std::map, или с питоновским dict, или с перловским hash, и помедитируй над результатом

Что-то я вообще перестал что-либо понимать:
#include <stdio.h>
#include <typeinfo>
#include "boost/static_assert.hpp"
#include "boost/mpl/map.hpp"
#include "boost/mpl/erase.hpp"
#include "boost/mpl/begin.hpp"
#include "boost/mpl/end.hpp"
#include "boost/mpl/front.hpp"
#include "boost/mpl/next.hpp"
#include "boost/mpl/insert.hpp"
#include "boost/mpl/size.hpp"

namespace mpl = ::boost::mpl;

template< class SeqT, bool IsEmpty = boost::is_same< typename mpl::begin< SeqT >::type, typename mpl::end< SeqT >::type >::value >
struct Print
{
    static void Do()
    {
        typedef typename mpl::front< SeqT >::type Head;
        ::printf("%s->%s, ", typeid(typename Head::first).name(), typeid(typename Head::second).name());
        Print< typename mpl::erase< SeqT, typename mpl::begin< SeqT >::type >::type >::Do();
    }
};
template< class SeqT >
struct Print< SeqT, true >
{
    static void Do() { ::printf("\n"); }
};

struct A {};
struct B {};
struct C {};
struct string {};

int main()
{
    typedef mpl::map< 
        mpl::pair< A, int > 
        , mpl::pair< B, char > 
        , mpl::pair< C, string > 
    >
    ::type m1;

    typedef mpl::insert< m1, mpl::pair< A, int > >::type m2;
    typedef mpl::insert< m1, mpl::pair< A, double > >::type m3;
    BOOST_STATIC_ASSERT( mpl::size< m2 >::value == mpl::size< m1 >::value );
    BOOST_STATIC_ASSERT( mpl::size< m3 >::value == mpl::size< m1 >::value + 1 );

    ::printf("m1:\n");
    Print< m1 >::Do();
    ::printf("m2:\n");
    Print< m2 >::Do();
    ::printf("m3:\n");
    Print< m3 >::Do();
}

Вывод:
m1:
struct A->int, struct B->char, struct C->struct string, 
m2:
struct A->int, struct B->char, struct C->struct string, 
m3:
struct A->int, struct A->int, struct B->char, struct C->struct string,
Re[4]: boost::map дубликаты ключей
От: jazzer Россия Skype: enerjazzer
Дата: 23.07.15 13:46
Оценка:
Здравствуйте, Warturtle, Вы писали:

W>Может я недостаточно ясно сформулировал вопрос, тогда замечу еще, что в первом сообщении у меня не срабатывают оба ассерта, т.е. программа компилится.


Вообще-то да, с этого надо было начать.

boost::mpl::map разрешает несколько разных значений для одного ключа.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[5]: boost::map дубликаты ключей
От: Warturtle  
Дата: 23.07.15 13:49
Оценка:
Здравствуйте, jazzer, Вы писали:

J>Здравствуйте, Warturtle, Вы писали:


W>>Может я недостаточно ясно сформулировал вопрос, тогда замечу еще, что в первом сообщении у меня не срабатывают оба ассерта, т.е. программа компилится.


J>Вообще-то да, с этого надо было начать.


J>boost::mpl::map разрешает несколько разных значений для одного ключа.

А как же тогда понимать вот это предложение из описания mpl::map:

A map may contain at most one element for each key.

?
Re[4]: boost::map дубликаты ключей
От: jazzer Россия Skype: enerjazzer
Дата: 23.07.15 13:54
Оценка: 4 (1)
Здравствуйте, Warturtle, Вы писали:

W>Что-то я вообще перестал что-либо понимать:

W>        Print< typename mpl::erase< SeqT, typename mpl::begin< SeqT >::type >::type >::Do();

W>Вывод:
W>struct A->int, struct A->int, struct B->char, struct C->struct string,


Проблема в том erase. Не надо так делать.
Попробуй так:
struct P
{
    template< typename U > void operator()(U x)
    {
        ::printf("%s->%s, ", typeid(typename U::first).name(), typeid(typename U::second).name());
    }
};
...
boost::mpl::for_each<m3>(P());

И получишь вот это:
struct A->int, struct B->char, struct C->struct string, struct A->double,
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[6]: boost::map дубликаты ключей
От: jazzer Россия Skype: enerjazzer
Дата: 23.07.15 14:12
Оценка: 4 (1)
Здравствуйте, Warturtle, Вы писали:

J>>boost::mpl::map разрешает несколько разных значений для одного ключа.

W>А как же тогда понимать вот это предложение из описания mpl::map:
W>

W>A map may contain at most one element for each key.

W>?
Лажа.
Там есть ниже, например

count<m,k>::type The number of elements with the key k in m


ну либо либо лажа в библиотеке
какие-то баг-репорты на тему вставки в мапу есть, типа вот: https://svn.boost.org/trac/boost/ticket/8749

В общем, если нужна уникальность, юзай has_key перед вставкой.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[7]: boost::map дубликаты ключей
От: Warturtle  
Дата: 23.07.15 14:18
Оценка:
Здравствуйте, jazzer, Вы писали:

J>Здравствуйте, Warturtle, Вы писали:


J>>>boost::mpl::map разрешает несколько разных значений для одного ключа.

W>>А как же тогда понимать вот это предложение из описания mpl::map:
W>>

W>>A map may contain at most one element for each key.

W>>?
J>Лажа.
J>Там есть ниже, например
J>

J>count<m,k>::type The number of elements with the key k in m


J>ну либо либо лажа в библиотеке

J>какие-то баг-репорты на тему вставки в мапу есть, типа вот: https://svn.boost.org/trac/boost/ticket/8749

J>В общем, если нужна уникальность, юзай has_key перед вставкой.

Спасибо, теперь понятно. Вообще-то им стоило бы тогда mpl::map мультимапом назвать, а то какие-то неверные ассоциации возникают. Тем более, что mpl::set ведет себя скорее как std::set, а не мультисет=)
Re[7]: boost::map дубликаты ключей
От: placement_new  
Дата: 23.07.15 14:19
Оценка:
Здравствуйте, jazzer, Вы писали:

Больше похоже на лажу в библиотеке
count это просто общий метод — он на все контейнеры распостраняется.

И не понятно как должен работать
at<m,k>::type
at<m,k,default>::type

Кстати, в рассылке кто то как то спрашивал про multimap — автор предложил просто использовать ключ -> контейнер.
Отредактировано 23.07.2015 14:24 placement_new . Предыдущая версия . Еще …
Отредактировано 23.07.2015 14:21 placement_new . Предыдущая версия .
Отредактировано 23.07.2015 14:21 placement_new . Предыдущая версия .
Re[8]: boost::map дубликаты ключей
От: placement_new  
Дата: 23.07.15 14:23
Оценка: +1
Здравствуйте, Warturtle, Вы писали:

W>Спасибо, теперь понятно. Вообще-то им стоило бы тогда mpl::map мультимапом назвать, а то какие-то неверные ассоциации возникают. Тем более, что mpl::set ведет себя скорее как std::set, а не мультисет=)


Кажется на mpl уже давно все забили в бусте.
Все ожидают новую библиотеку с более говорящим название HANA (ХАНА!).
Re[8]: boost::map дубликаты ключей
От: jazzer Россия Skype: enerjazzer
Дата: 23.07.15 14:25
Оценка:
Здравствуйте, Warturtle, Вы писали:

J>>В общем, если нужна уникальность, юзай has_key перед вставкой.


W>Спасибо, теперь понятно. Вообще-то им стоило бы тогда mpl::map мультимапом назвать, а то какие-то неверные ассоциации возникают. Тем более, что mpl::set ведет себя скорее как std::set, а не мультисет=)


Не, мультимап позволяет полные дубликаты, а этот — нет
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[9]: boost::map дубликаты ключей
От: Warturtle  
Дата: 23.07.15 14:36
Оценка:
Здравствуйте, placement_new, Вы писали:

_>Здравствуйте, Warturtle, Вы писали:


W>>Спасибо, теперь понятно. Вообще-то им стоило бы тогда mpl::map мультимапом назвать, а то какие-то неверные ассоциации возникают. Тем более, что mpl::set ведет себя скорее как std::set, а не мультисет=)


_>Кажется на mpl уже давно все забили в бусте.

_>Все ожидают новую библиотеку с более говорящим название HANA (ХАНА!).
Ну хана так хана — посмотрим=) Хотя все-таки немного интересно почему они это так реализовали: изначальный недосмотр+"вообщепоx" или "бай дизайн".
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.