Boost logo

Boost Users :

From: Mark Schlegel (moschleg_at_[hidden])
Date: 2007-09-20 13:55:56


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


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