[multi-index]/shared_ptr template issue - compiles on MSVC8 but not gcc
Hi, I'm using boost versions 1.33.1 and 1.34.1 with gcc 4.1.2 (Linux) and boost 1.33.1 with gcc 3.3.2 on solaris and MSVC8 I'm trying to use multi_index as a container indexed by two integers in a class called MapEntry. The two indices represent a unique key number "key" and a possibly non-unique timestamp "age". To make it generic I have the data in a shared_ptr<T> in the MapEntry class because I wanted to use the aged map functionality with many classes in the shared_ptr: // the tags struct keytag { }; struct agetag { }; template <typename T> struct MapEntry { .... stripped out all constructors and methods ... int key; int age; private: boost::shared_ptr<T> payload; }; and the multi_index_container setup as a wrapper class since C++ doesn't have typedef templates because I figured I needed that to get the "T" into the MapEntry<T> .... template<typename T> class AgedMap { typedef T map_type; public: typedef multi_index_container< MapEntry<T>, indexed_by< ordered_unique< tag<keytag>, BOOST_MULTI_INDEX_MEMBER(MapEntry<T>, int, key) >, ordered_non_unique< tag<agetag>, BOOST_MULTI_INDEX_MEMBER(MapEntry<T>, int, age) > > > AGEDMAPTYPE; }; and in main() I declare the container as: AgedMap<AH_ENTRY>::AGEDMAPTYPE am; and do insert, finds and erases into it. My problem is that it seems that if I use the T template to call my flush_by_age template function : template <typename T, typename MIContainer> void flush_by_age(MIContainer& mic, int timeout) { ..... which is called from main() as (note AH_ENTRY is a very simple struct with just a single int in it and cctor/ctor/dtor for testing) flush_by_age<AH_ENTRY, AHS_MAP>(am, AGELIMIT); and use that T to define what AGE_INDEX is inside it: // this hard coded one compiles and runs on all my platforms // but loses the whole point of genericness //typedef AgedMap<AH_ENTRY>::AGEDMAPTYPE::index<agetag>::type AGE_INDEX; // this AGE_INDEX does not on gcc but DOES compile on MSVC8 typedef AgedMap<T>::AGEDMAPTYPE::index<agetag>::type AGE_INDEX; I get a compiler error at the AGE_INDEX typedef in gcc 3.3.2 (solaris 10): aged_map.cc: In function `void flush_by_age(MIContainer&, int)': aged_map.cc:159: warning: `boost::multi_index::multi_index_container<Value1, IndexSpecifierList1, Allocator1>::index<agetag>::type' is implicitly a typename and a more verbose one on gcc 4.1.2 (Fedora 6 Linux): aged_map.cc: In function âvoid flush_by_age(MIContainer&, int)â: aged_map.cc:159: error: non-template 'index' used as template aged_map.cc:159: note: use âboost::multi_index::multi_index_container<MapEntry<T>, boost::multi_index::indexed_by<boost::multi_index::ordered_unique< boost::multi_index::tag<keytag, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, boost::multi_index::member<MapEntry<T>, int, (& MapEntry<T>::key)>, mpl_::na>, boost::multi_index::ordered_non_unique< boost::multi_index::tag<agetag, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, boost::multi_index::member<MapEntry<T>, int, (& MapEntry<T>::age)>, mpl_::na>, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, std::allocator<MapEntry<T> > >::template index' to indicate that it is a template aged_map.cc:159: error: too few template-parameter-lists But MSVC 8 compiles it fine and it runs. But if I hard code the class in my AGE_INDEX typedef to "<AH_ENTRY>" to replace the <T> in the flush_by_age() it compiles fine on ALL those compilers and they all run ok. I'm wanting to find out what I can possibly do because this would be a very useful class for since I currently have to put the aging information in another container where this let's me do it in one. I use unix and Windows and on Windows the compiler must be MSVC and on unix gcc. I tried making the typename explicit by adding "typename" using the hint from the solaris error but that didn't help. I'm guessing I've got some syntax typo like a missing & or const somewhere ? thanks, Mark
Mark Schlegel:
// this hard coded one compiles and runs on all my platforms // but loses the whole point of genericness //typedef AgedMap<AH_ENTRY>::AGEDMAPTYPE::index<agetag>::type AGE_INDEX;
// this AGE_INDEX does not on gcc but DOES compile on MSVC8 typedef AgedMap<T>::AGEDMAPTYPE::index<agetag>::type AGE_INDEX;
Try adding 'typename' after 'typedef'.
Hello Mark, ----- Mensaje original ----- De: Mark Schlegel <moschleg@verizon.net> Fecha: Jueves, Septiembre 20, 2007 11:24 pm Asunto: [Boost-users] [multi-index]/shared_ptr template issue - compiles on MSVC8 but not gcc Para: boost-users@lists.boost.org [...]
// this AGE_INDEX does not on gcc but DOES compile on MSVC8 typedef AgedMap<T>::AGEDMAPTYPE::index<agetag>::type AGE_INDEX;
The correct syntax is typedef typename AgedMap<T>::AGEDMAPTYPE::template index<agetag>::type AGE_INDEX; (note the intervening template keyword) which, just for succintness, in your particular ought to be the same, I think, as typedef typename MIContainer::template index<agetag>::type AGE_INDEX; The dependent template keyword can cause problems in non-conformant compilers. If you meet those, try the variants: typedef typename boost::multi_index::index< typename AgedMap<T>::AGEDMAPTYPE,agetag>::type AGE_INDEX; or typedef typename boost::multi_index::index< MIContainer,agetag>::type AGE_INDEX; Good luck, Joaquín M López Muñoz Telefónica, Investigación y Desarrollo
participants (3)
-
"JOAQUIN LOPEZ MU?Z"
-
Mark Schlegel
-
Peter Dimov