boost::multi_index_container et accesseurs
Bonjour,
J'utilise un multi_index_container pour avoir une liste d'elements dont je veux conserver l'ordre d'insertion, mais aussi pouvoir les trier selon une clef de type string non unique :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
|
#include <Windows.h>
#include <iostream>
#include <string>
#include <time.h>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/sequenced_index.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/ordered_index.hpp>
class Element
{
public:
Element(const std::string& str)
: m_strValue(str)
, m_iRand(rand())
{
}
inline const std::string& getValue(void) const {return m_strValue;}
inline int getRand(void) const {return m_iRand;}
bool operator<(const Element& ref) const
{
return m_strValue < ref.m_strValue;
}
private:
Element(const Element& rCopy)
{
}
const Element& operator=(const Element& rCopy)
{
}
public:
int m_iRand;
std::string m_strValue;
};
struct byValue{};
typedef boost::multi_index_container<
Element *,
boost::multi_index::indexed_by<
boost::multi_index::sequenced<>,
boost::multi_index::ordered_non_unique<
boost::multi_index::tag<byValue>,
boost::multi_index::member<Element, std::string, &Element::m_strValue>
>
>
> ElementSet;
#if defined(BOOST_NO_MEMBER_TEMPLATES)
typedef boost::multi_index::nth_index<ElementSet, 1>::type ElementSetByValue;
#else
typedef ElementSet::nth_index<1>::type ElementSetByValue;
#endif
int main(int ac, char **av)
{
ElementSet setElements;
srand(static_cast<unsigned int>(time(NULL)));
setElements.get<1>().insert(ElementSet::value_type(new Element("Plop")));
setElements.get<1>().insert(ElementSet::value_type(new Element("Abc")));
setElements.get<1>().insert(ElementSet::value_type(new Element("Zzz")));
setElements.get<1>().insert(ElementSet::value_type(new Element("Plop")));
setElements.get<1>().insert(ElementSet::value_type(new Element("Plop")));
setElements.get<1>().insert(ElementSet::value_type(new Element("Machin")));
std::cout << "[ Element ordered by insertion ]" << std::endl;
for (ElementSet::iterator itElement = setElements.begin(); itElement != setElements.end(); ++itElement)
std::cout << "\tELement : (" << (*itElement)->getValue() << ", " << (*itElement)->getRand() << ")" << std::endl;
std::cout << std::endl << "[ Element ordered by Value ]" << std::endl;
for (ElementSetByValue::iterator itElement = setElements.get<byValue>().begin(); itElement != setElements.get<byValue>().end(); ++itElement)
std::cout << "\tELement : (" << (*itElement)->getValue() << ", " << (*itElement)->getRand() << ")" << std::endl;
std::cout << std::endl << std::endl << "[ Find Element Plop (ordered by insertion) ]" << std::endl;
std::pair<ElementSetByValue::iterator, ElementSetByValue::iterator> p = setElements.get<byValue>().equal_range("Plop");
for (ElementSetByValue::iterator itElement = p.first; itElement != p.second; ++itElement)
std::cout << "\tELement : (" << (*itElement)->getValue() << ", " << (*itElement)->getRand() << ")" << std::endl;
std::cout << std::endl;
system("pause");
return 0;
} |
les résultats obtenu sont bien ce que je cherche a avoir :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
[ Element ordered by insertion ]
ELement : (Plop, 12346)
ELement : (Abc, 6087)
ELement : (Zzz, 7093)
ELement : (Plop, 21721)
ELement : (Plop, 15503)
ELement : (Machin, 26172)
[ Element ordered by Value ]
ELement : (Abc, 6087)
ELement : (Machin, 26172)
ELement : (Plop, 12346)
ELement : (Plop, 21721)
ELement : (Plop, 15503)
ELement : (Zzz, 7093)
[ Find Element Plop (ordered by insertion) ]
ELement : (Plop, 12346)
ELement : (Plop, 21721)
ELement : (Plop, 15503) |
j'ai deux points qui m’embête avec cette implémentation (surtout le premier) :
- je ne veux pas que le membre m_strValue de la classe Element soit public.
- le deuxième est lie au premier, je voudrais que mes typedef ElementSet ElementSetByValue et la struct byValue soient interne a la classe Element.
J'en suis bloque la, je ne sais pas comment dire a boost de ne pas utiliser member<Element, std::string, &Element::m_strValue) mais plutôt Element::getValue(), et impossible aussi de mette le tout interne a Element sinon erreur du genre type Element non défini...