Question

I am currently using Boost::multi_index_container and its working great. However I wanted to encapsulate the code and create a template class that looks like this

template<class T>
class LookUp
{
    boost::multi_index<T, indexed_by<___predefined indices___> > myTable;

    void Foo();
}

Essentially there are predefined indices used in this wrapper, but for a specialised T, I also want to add additional indices. Is it possible to add additional indices to myTable? Maybe additional template arguments? But the number of additional indices are unknown.

No correct solution

OTHER TIPS

Have a trait. Let's invent:

namespace traits
{
    template <typename T> struct predefined_indexes;
}


template <typename T> using MultiIndex = multi_index_container<T, traits::predefined_indexes<T> >;

Now the idea is we can instantiate our MICs:

MultiIndex<T> myTable;

Let's try with a simple example:

//////
// example from http://www.boost.org/doc/libs/1_55_0/libs/multi_index/example/fun_key.cpp
struct name_record
{
    name_record(std::string given_name_,std::string family_name_): given_name(given_name_),family_name(family_name_) {}
    std::string name() const { return family_name + " " + given_name; }
    std::string given_name, family_name;
};

std::string::size_type name_record_length(const name_record& r)
{
    return r.name().size();
}

namespace traits
{
    template <> struct predefined_indexes<name_record> :
        indexed_by<
            ordered_unique<
                BOOST_MULTI_INDEX_CONST_MEM_FUN(name_record,std::string,name)
            >,
            ordered_non_unique<
                global_fun<const name_record&,std::string::size_type,name_record_length>
            >
        >
    {
    };
}

See it Working Live On Coliru

int main()
{
    using MyTable = MultiIndex<name_record>;
    MyTable myTable;

    myTable.insert(name_record("Joe","Smith"));
    myTable.insert(name_record("Robert","Nightingale"));
    myTable.insert(name_record("Robert","Brown"));
    myTable.insert(name_record("Marc","Tuxedo"));

    /* list the names in myTable in phonebook order */
    std::cout << "Phonenook order\n" << "---------------" << std::endl;
    for(MyTable::iterator it=myTable.begin();it!=myTable.end();++it){
        std::cout << it->name() << std::endl;
    }

    /* list the names in myTable according to their length*/

    std::cout<<"\nLength order\n"
        <<  "------------"<<std::endl;
    for(nth_index<MyTable,1>::type::iterator it1=get<1>(myTable).begin();
            it1!=get<1>(myTable).end();++it1){
        std::cout<<it1->name()<<std::endl;
    }
}

Output

Phonenook order
---------------
Brown Robert
Nightingale Robert
Smith Joe
Tuxedo Marc

Length order
------------
Smith Joe
Tuxedo Marc
Brown Robert
Nightingale Robert
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top