STL : std::set problème avec insert ...
Bonjour,
j'aimerais utilisé std::set, mais j'ai quelques ennuis ...
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| // ------
class SCImports
{
public:
SCImports(const std::string & etat1, const std::string & etat2)
: nom1(etat1),nom2(etat2)
{
}
std::string nom1;
std::string nom2;
};
// ------
// déclaration dans une autre classe Test
std::set<SCImports> listeSCImports;
// ------
// utilisation dans cette autre classe Test
((std::set<SCImports>) listeMaClasse).insert((SCImports)classe); |
Si je compile la classe Test, j'obiens de visual 2002 cette erreur :
C:\Program Files\Microsoft Visual Studio .NET\Vc7\include\functional(139): error C2676: binary '<' : 'const SCImports' does not define this operator or a conversion to a type acceptable to the predefined operator
d'où ma question, est-ce que je dois surcharger l'opérateur "<" ?
Est-ce que ça ne devrait pas plutôt être l'opérateur "==" pour déterminer si la clé (l'élément à insérer) est déjà présent dans la "liste" set ?
Si je dois surcharger l'opérateur comment je fais avec ma classe qui a seulement 2 string en attribut, et plus intéressant comment je fais si c'est une classe qui a plein d'attributs ?
Merci de vos réponses, j'espère avoir été clair. Cependant, il se peut que je n'ai pas bien compris le fonctionnement de set (qui pour moi est une sorte de liste de clé donc impossible d'avoir 2 fois la même clé dans set), si c'est le cas merci de me donner d'autres informations...
En passant, un lien intéressant sur les containers :
http://www.mines.u-nancy.fr/~tombre/...olyCpp008.html
Big. K
Re: STL : std::set problème avec insert ...
Citation:
Envoyé par Big K.
Bonjour,
C:\Program Files\Microsoft Visual Studio .NET\Vc7\include\functional(139): error C2676: binary '<' : 'const SCImports' does not define this operator or a conversion to a type acceptable to the predefined operator
d'où ma question, est-ce que je dois surcharger l'opérateur "<" ?
Est-ce que ça ne devrait pas plutôt être l'opérateur "==" pour déterminer si la clé (l'élément à insérer) est déjà présent dans la "liste" set ?
Pour utiliser 'set' il faut disposer d'un moyen de comparer deux éléments.
Il est possible de fournir une telle fonction lors de l'instanciation du template.
Si aucune fonction de comparaison n'est fournie alors '<' est utilisé par défaut.
La fonction doit définir une relation d'ordre faible entre les éléments du set.
Pour plus d'info http://www.sgi.com/tech/stl/set.html
Le truc à retenir c'est que la comparaison doit être irreflexive. C-à-d que 'compare(a, a)' retourne faux. En gros, ça marche avec '<' ou '>' mais pas avec '<=' ou '>='
Pour résoudre le problème il y a alors deux façon de faire:
- surcharger l'opérateur < (pas terrible).
- définir une fonction de comparaison.
On peux, par exemple, concaténer les deux chaînes et de les comparer.
Par exemple
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
struct SCImportsCompare
{
bool operator()(const SCImports& lhs, const SCImports& rhs) const
{
string s1(lhs.nom1);
s1.append(lhs.nom2);
string s2(rhs.nom1);
s1.append(rhs.nom2);
return ( s1.compare(s2) < 0 );
}
};
// Création du Set
set<SCImports, SCImportsCompare> mySet; |