boost::multi_index, std::set_intersection
От: uzverg  
Дата: 10.09.08 11:06
Оценка:
Не работает пересечение множеств, немогу понять в чем проблема?

Console output:
es1 by name
A x=22 y=5
B x=7 y=9
Joe x=1 y=31

es2 by name
A x=22 y=5
B x=5 y=33
CC x=1 y=2
O x=1 y=2
P x=7 y=9

es3 by name

Для продолжения нажмите любую клавишу . . .



#if !defined(NDEBUG)
#define BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING
#define BOOST_MULTI_INDEX_ENABLE_SAFE_MODE
#endif

#include <boost/multi_index_container.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <algorithm>
#include <iostream>
#include <iterator>
#include <string>

using boost::multi_index_container;
using namespace boost::multi_index;

class Entity
{
    public:
        std::string name;
        int x, y;
        Entity(std::string name, int x, int y)
        {
            Entity::name = name;
            Entity::x = x;
            Entity::y = y;
        }
  
  friend std::ostream& operator<<(std::ostream& os,const Entity& e)
  {
    os<<e.name<<" x="<<e.x<<" y="<<e.y<<std::endl;
    return os;
  }
  
  friend bool operator<(const Entity& e1, const Entity& e2)
  {
    return (e1.name < e2.name);
  }
};

struct iname{};
struct ix{};
struct iy{};


typedef multi_index_container<
  Entity *,
  indexed_by<
    ordered_unique< tag<iname>, identity<Entity> >,
    ordered_non_unique< 
        tag<ix>, BOOST_MULTI_INDEX_MEMBER(Entity,int, x)>,
    ordered_non_unique<
        tag<iy>, BOOST_MULTI_INDEX_MEMBER(Entity,int, y)> >
> Entity_set;

///////
class displayEntity
{
    public:
    void operator()(const Entity* eP) const
    {
        std::cout << *eP;
    }
};

template<typename Tag,typename MultiIndexContainer>

void print_out_by(
 const MultiIndexContainer& s,
 Tag* =0 /* fixes a MSVC++ 6.0 bug with implicit template function parms */)
{
  /* obtain a reference to the index tagged by Tag */
  const typename boost::multi_index::index<MultiIndexContainer,Tag>::type& i=
    get<Tag>(s);
  typedef typename MultiIndexContainer::value_type value_type;

  for_each(i.begin(), i.end(), displayEntity());
}

int main()
{
    Entity_set es1, es2, es3;

    es1.insert(new Entity("Joe", 1,31));
    es1.insert(new Entity("A", 22,5));
    es1.insert(new Entity("B", 7, 9));
    
    es2.insert(new Entity("JIM", 88, 88)); //TEST REMOVE
    es2.insert(new Entity("A", 22,5));
    es2.insert(new Entity("O", 1, 2));
    es2.insert(new Entity("B", 5, 33));
    es2.insert(new Entity("P", 7, 9));
    es2.insert(new Entity("CC", 1, 2));
    es2.erase(Entity("JIM", 88, 88)); //TEST REMOVE

    std::cout<<"es1 by name"<<std::endl;
    print_out_by<iname>(es1);
    std::cout<<std::endl;
    
    std::cout<<"es2 by name"<<std::endl;
    print_out_by<iname>(es2);
    std::cout<<std::endl;

    // INTERSECTION 
    std::set_intersection(es1.begin(), es1.end(), es2.begin(), es2.end(), std::inserter(es3, es3.end()));
        
    std::cout<<"es3 by name"<<std::endl;
    print_out_by<iname>(es3);
    std::cout<<std::endl;
    
    system("PAUSE");
    return 0;
}


boost multi_index set_intersection
Re: boost::multi_index, std::set_intersection
От: Кодт Россия  
Дата: 10.09.08 11:30
Оценка: 2 (1)
Здравствуйте, uzverg, Вы писали:

U>Не работает пересечение множеств, немогу понять в чем проблема?


Проблема в том, что set_intersection работает с компаратором над элементами. А элементы у тебя — это указатели.
Нужно подсунуть специальный компаратор
struct dereferenced_less
{
    template<class T>
    bool operator()(T* x, T* y) const { return *x < *y; }
};

.....
set_intersection(es1.begin(),es1.end(), es2.begin(),es2.end(), inserter(es3,es3.end()), dereferenced_less());
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Перекуём баги на фичи!
Re[2]: boost::multi_index, std::set_intersection
От: jazzer Россия Skype: enerjazzer
Дата: 11.09.08 12:08
Оценка:
Здравствуйте, Кодт, Вы писали:

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


U>>Не работает пересечение множеств, немогу понять в чем проблема?


К>Проблема в том, что set_intersection работает с компаратором над элементами. А элементы у тебя — это указатели.

К>Нужно подсунуть специальный компаратор
К>
К>set_intersection(es1.begin(),es1.end(), es2.begin(),es2.end(), inserter(es3,es3.end()), dereferenced_less());
К>


Ну, раз уж все равно буст используется, то можно и лямбду заюзать напрямую:

set_intersection(
  es1.begin(), es1.end(),
  es2.begin(), es2.end(),
  inserter( es3, es3.end() ),
  *_1 < *_2 );

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::multi_index, std::set_intersection
От: Кодт Россия  
Дата: 11.09.08 12:21
Оценка:
Здравствуйте, jazzer, Вы писали:

J>Ну, раз уж все равно буст используется, то можно и лямбду заюзать напрямую:


Побоялся советовать лямбду после
void print_out_by(
 const MultiIndexContainer& s,
 Tag* =0 /* fixes a MSVC++ 6.0 bug with implicit template function parms */)
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Перекуём баги на фичи!
Re[4]: boost::multi_index, std::set_intersection
От: jazzer Россия Skype: enerjazzer
Дата: 11.09.08 12:34
Оценка:
Здравствуйте, Кодт, Вы писали:

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


J>>Ну, раз уж все равно буст используется, то можно и лямбду заюзать напрямую:


К>Побоялся советовать лямбду после

К>
К> Tag* =0 /* fixes a MSVC++ 6.0 bug with implicit template function parms */)
К>

да, действительно...

хотя, может, для такого простого случая она сработает.
В конце концов, мультииндекс — тоже не самая простая библиотека...
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.