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 : Sélectionner tout - Visualiser dans une fenêtre à part
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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...