$include_dir="/home/hyper-archives/boost-users/include"; include("$include_dir/msg-header.inc") ?>
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