|
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