В настоящее время я использую Boost :: multi_index_container и он отлично работает. Однако я хотел инкапсулировать код и создать шаблонный класс, который выглядит следующим образом
template<class T>
class LookUp
{
boost::multi_index<T, indexed_by<___predefined indices___> > myTable;
void Foo();
}
По сути, в этой оболочке используются предопределенные индексы, но для специализированного T я также хочу добавить дополнительные индексы. Можно ли добавить дополнительные индексы к myTable
? Может быть, дополнительные аргументы шаблона? Но количество дополнительных показателей неизвестно.
Имей черту. Давайте изобретать:
namespace traits
{
template <typename T> struct predefined_indexes;
}template <typename T> using MultiIndex = multi_index_container<T, traits::predefined_indexes<T> >;
Теперь идея состоит в том, что мы можем создать наши MIC:
MultiIndex<T> myTable;
Давайте попробуем на простом примере:
//////
// 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>
>
>
{
};
}
Видеть это Работаем в прямом эфире на Колиру
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;
}
}
Выход
Phonenook order
---------------
Brown Robert
Nightingale Robert
Smith Joe
Tuxedo Marc
Length order
------------
Smith Joe
Tuxedo Marc
Brown Robert
Nightingale Robert
Других решений пока нет …