Boost logo

Boost Users :

From: damny_at_[hidden]
Date: 2008-04-19 11:42:20


hi joaquin,

a)
here's a ready to use code snippet (see below).
i isolating the problem by writing the snippet to the reuse of objects or using local temporary objects;
i thought multi_index maps store copies of data objects, that where inserted.
am i wrong?

b)
why it isn't possible to write (with "?" is a class attribute or template parameter; see snippet):

template<typename MAP, typename ELM, typename SC1, typename IT1, typename SC2, typename IT2>
const ELM *tCanMap<MAP,ELM,SC1,IT1,SC2,IT2>::getmapelm(STRING stNme) const {
   IT1 itr = this->_mpMap.get<?>().find(stNme);
   if ( itr != this->_mpMap.get<?>().end() ) { return &(*itr); }
}

thank you
daniel

//--- BEG ----------------------------------------------------------------------

#if defined(_Windows) || defined(_MSC_VER) || defined (__GNUC__)
 #define STRICT
 #include <windows.h>
#endif

#include <string>

#define BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING
#define BOOST_MULTI_INDEX_ENABLE_SAFE_MODE
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/mem_fun.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/hashed_index.hpp>

//------------------------------------------------------------------------------

#define UINT32 unsigned long
#define STRING std::string

//------------------------------------------------------------------------------

// choose one
//#define VERSION01
//#define VERSION02
//#define VERSION03
//#define VERSION04

//------------------------------------------------------------------------------

template<typename MAP, typename ELM, typename SC1, typename IT1, typename SC2, typename IT2>
class tCanMap {
  protected:
    mutable MAP _mpMap; // map
    mutable SC1 *_scNme; // sorting criteria name ... have to init from derived class
    mutable SC2 *_scDat; // sorting criteria name ... have to init from derived class
  public:
                     tCanMap ();
             MAP &getmap () const;
             UINT32 setmapelm (ELM val);
#if defined (VERSION01) || defined (VERSION02)
    const ELM *getmapelm (STRING stNme) const;
    const ELM *getmapelm (UINT32 uiDat) const;
#endif
};

template<typename MAP, typename ELM, typename SC1, typename IT1, typename SC2, typename IT2>
tCanMap<MAP,ELM,SC1,IT1,SC2,IT2>::tCanMap() {
  this->_scNme = NULL;
  this->_scDat = NULL;
}

template<typename MAP, typename ELM, typename SC1, typename IT1, typename SC2, typename IT2>
MAP &tCanMap<MAP,ELM,SC1,IT1,SC2,IT2>::getmap() const {
  return this->_mpMap;
}

template<typename MAP, typename ELM, typename SC1, typename IT1, typename SC2, typename IT2>
UINT32 tCanMap<MAP,ELM,SC1,IT1,SC2,IT2>::setmapelm(ELM val) {
  if (this!=NULL) { this->_mpMap.insert(val); return 0; }
  return 1;
}

#if defined (VERSION01) || defined (VERSION02)
template<typename MAP, typename ELM, typename SC1, typename IT1, typename SC2, typename IT2>
const ELM *tCanMap<MAP,ELM,SC1,IT1,SC2,IT2>::getmapelm(STRING stNme) const {
  try {
    if ( this!=NULL && this->_scNme!=NULL ) {
      IT1 itr = this->_scNme->find(stNme);
      if ( itr != this->_scNme->end() ) { return &(*itr); }
    }
  }
  catch(...) {}
  return NULL;
}

template<typename MAP, typename ELM, typename SC1, typename IT1, typename SC2, typename IT2>
const ELM *tCanMap<MAP,ELM,SC1,IT1,SC2,IT2>::getmapelm(UINT32 uiDat) const {
  try {
    if ( this!=NULL && this->_scDat!=NULL ) {
      IT2 itr = this->_scDat->find(uiDat);
      if ( itr != this->_scDat->end() ) { return &(*itr); }
    }
  }
  catch(...) {}
  return NULL;
}
#endif

//------------------------------------------------------------------------------

class cClass00 {
  private:
    STRING _nme;
    UINT32 _dat;
  public:
           cClass00() {}
           cClass00(STRING nme, UINT32 dat) { this->_nme=nme; this->_dat=dat; }
    STRING getnme () const { return this->_nme; }
    UINT32 getdat () const { return this->_dat; }
};

typedef boost::multi_index_container <
  cClass00,
  boost::multi_index::indexed_by <
    boost::multi_index::hashed_unique < BOOST_MULTI_INDEX_CONST_MEM_FUN(cClass00,STRING,getnme) >,
    boost::multi_index::ordered_unique < BOOST_MULTI_INDEX_CONST_MEM_FUN(cClass00,UINT32,getdat) >
>
> mClass00;

typedef mClass00::nth_index<0>::type mClass00ByNme;
typedef mClass00ByNme::iterator mClass00ByNmeItr;

typedef mClass00::nth_index<1>::type mClass00ByDat;
typedef mClass00ByDat::iterator mClass00ByDatItr;

//------------------------------------------------------------------------------

class cClass01 : public tCanMap<mClass00,cClass00,mClass00ByNme,mClass00ByNmeItr,mClass00ByDat,mClass00ByDatItr> {
  private:
    STRING _nme;
    UINT32 _dat;
  public:
           cClass01() {}
           cClass01(STRING nme, UINT32 dat) { this->_nme=nme; this->_dat=dat; this->_scNme = &(this->_mpMap.get<0>()); this->_scDat = &(this->_mpMap.get<1>()); }
    STRING getnme() const { return this->_nme; }
    UINT32 getdat() const { return this->_dat; }
#if defined (VERSION03) || defined (VERSION04)
    const cClass00 *getmapelm (STRING stNme) const {
      try { if ( this!=NULL ) { mClass00ByNmeItr itr = this->_mpMap.get<0>().find(stNme); if ( itr != this->_mpMap.get<0>().end() ) { return &(*itr); } } }
      catch(...) {}
      return NULL;
    }
    const cClass00 *getmapelm (UINT32 uiDat) const {
      try { if ( this!=NULL ) { mClass00ByDatItr itr = this->_mpMap.get<1>().find(uiDat); if ( itr != this->_mpMap.get<1>().end() ) { return &(*itr); } } }
      catch(...) {}
      return NULL;
    }
#endif

};

typedef boost::multi_index_container <
  cClass01,
  boost::multi_index::indexed_by <
    boost::multi_index::hashed_unique < BOOST_MULTI_INDEX_CONST_MEM_FUN(cClass01,STRING,getnme) >,
    boost::multi_index::ordered_unique < BOOST_MULTI_INDEX_CONST_MEM_FUN(cClass01,UINT32,getdat) >
>
> mClass01;

typedef mClass01::nth_index<0>::type mClass01ByNme;
typedef mClass01ByNme::iterator mClass01ByNmeItr;

typedef mClass01::nth_index<1>::type mClass01ByDat;
typedef mClass01ByDat::iterator mClass01ByDatItr;

//------------------------------------------------------------------------------

class cClass02 : public tCanMap<mClass01,cClass01,mClass01ByNme,mClass01ByNmeItr,mClass01ByDat,mClass01ByDatItr> {
  public:
    cClass02() { this->_scNme = &(this->_mpMap.get<0>()); this->_scDat = &(this->_mpMap.get<1>()); }
#if defined (VERSION03) || defined (VERSION04)
    const cClass01 *getmapelm (STRING stNme) const {
      try { if ( this!=NULL ) { mClass01ByNmeItr itr = this->_mpMap.get<0>().find(stNme); if ( itr != this->_mpMap.get<0>().end() ) { return &(*itr); } } }
      catch(...) {}
      return NULL;
    }
    const cClass01 *getmapelm (UINT32 uiDat) const {
      try { if ( this!=NULL ) { mClass01ByDatItr itr = this->_mpMap.get<1>().find(uiDat); if ( itr != this->_mpMap.get<1>().end() ) { return &(*itr); } } }
      catch(...) {}
      return NULL;
    }
#endif
};

//------------------------------------------------------------------------------

int main(void) {
#if defined (VERSION01) || defined (VERSION03)
// works fine in any case
  cClass00 objClass00_01 = cClass00( "elm00_01", 1 );
  cClass00 objClass00_02 = cClass00( "elm00_02", 2 );
  cClass00 objClass00_03 = cClass00( "elm00_03", 3 );
  cClass00 objClass00_04 = cClass00( "elm00_04", 4 );

  cClass01 objClass01_01 = cClass01( "elm01_01", 11 );
  cClass01 objClass01_02 = cClass01( "elm01_02", 12 );

  objClass01_01.setmapelm( objClass00_01 );
  objClass01_01.setmapelm( objClass00_02 );
  objClass01_02.setmapelm( objClass00_03 );
  objClass01_02.setmapelm( objClass00_04 );

  cClass02 *ptrClass02_01 = new cClass02();

  ptrClass02_01->setmapelm( objClass01_01 );
  ptrClass02_01->setmapelm( objClass01_02 );

  printf("START\n");
  printf("\n");
  printf( "1. try: %02d\n", ptrClass02_01->getmapelm("elm01_01")->getdat() );
  printf( "2. try: %02d\n", ptrClass02_01->getmapelm("elm01_02")->getdat() );
  printf("\n");
  printf( "3. try: %02d\n", ptrClass02_01->getmapelm("elm01_01")->getmapelm("elm00_01")->getdat() );
  printf( "4. try: %02d\n", ptrClass02_01->getmapelm("elm01_02")->getmapelm("elm00_04")->getdat() );
  printf("\n");
  printf( "5. try: %s\n", ptrClass02_01->getmapelm("elm01_01")->getmapelm(2)->getnme().c_str() );
  printf( "6. try: %s\n", ptrClass02_01->getmapelm("elm01_02")->getmapelm(3)->getnme().c_str() );
  printf("\n");
  printf("DONE\n");
#elif defined (VERSION02) || defined (VERSION04)
// run into segvault if object become overwritten OR
// object for filling multi_index is only a local variable of a filling function
  cClass02 *ptrClass02 = new cClass02();
  cClass01 objClass01;
  cClass00 objClass00;

  objClass01 = cClass01("elm01_01", 11);
  objClass00 = cClass00("elm00_01", 1); objClass01.setmapelm(objClass00);
  objClass00 = cClass00("elm00_02", 2); objClass01.setmapelm(objClass00);

  objClass01 = cClass01("elm01_02", 12);
  objClass00 = cClass00("elm00_03", 4); objClass01.setmapelm(objClass00);
  objClass00 = cClass00("elm00_04", 3); objClass01.setmapelm(objClass00);

  ptrClass02->setmapelm(objClass01);

  printf("START\n");
  printf( "dat = %d\n", ptrClass02->getmapelm("elm01_01")->getdat() ); // seg_vault
// printf( "dat = %d\n", ptrClass02->getmapelm("elm01_02")->getdat() ); // works fine
  printf("DONE\n");
#endif
}

//--- END ----------------------------------------------------------------------

______________________________________________________
Bis 50 MB Dateianhänge? Kein Problem!
http://freemail.web.de/club/landingpage.htm/?mc=025556


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net