Et bon, je trouve plus propre d'avoir un swap dans ton namespace et laissez l'ADL le trouver plutot que de hacker std. mais comme dis plus, préférences personelles.
Et bon, je trouve plus propre d'avoir un swap dans ton namespace et laissez l'ADL le trouver plutot que de hacker std. mais comme dis plus, préférences personelles.
On peut pas spécialiser partiellement une fonction template...
Sinon +1 pour l'ADL. J'aime pas ouvrir le namespace std dans mes fichiers... C'est psychologique sûrement.
"Hardcoded types are to generic code what magic constants are to regular code." --A. Alexandrescu
argument dependent name lookup
C'est ce qui te permet d'écrire :
std::cout << "foo";
sans soucis. (ie t'éviter std::cout std::operator<<("foo"); )
"Hardcoded types are to generic code what magic constants are to regular code." --A. Alexandrescu
lol, on aprend des choses tous les jours
Par contre, comment tu définie le swap dans ton namespace pour que l'ADL trouve la bonne implémentation pour la STL?
J'ai beau essayer, j'y arrive pas (sous visual 2008)
dans ce code, seule la spécialisation de la std est appelé lors du sort.
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 #include <algorithm> #include <iostream> #include <vector> #include <string> namespace AA { class A { public : A(int a) :nb(a) { }; bool operator<(const A& a) { return nb<a.nb; } A& operator=(const A& a) { nb = a.nb; return (*this); } void swap(A& a) { std::swap(nb,a.nb); }; private: int nb; }; template<typename T> void swap ( T& a, T& b ) { std::cout<<"AA::std::swap"<<std::endl; std::swap(a,b); }; //specialisation de la fonction swap pour la class A template<> void swap<A> ( A& a, A& b ) { std::cout<<"AA::swap"<<std::endl; a.swap(b); }; }//fin namespace template<> void std::swap<AA::A> ( AA::A& a, AA::A& b ) { std::cout<<"std::swap"<<std::endl; a.swap(b); }; int main(int argc, char** argv) { //mon vecteur a trier std::vector<AA::A> vect; //on remplie de n'importe quoi for(int i =0 ; i < 1000 ; ++i) vect.push_back(AA::A(rand())); //on fait le trie std::sort(vect.begin(),vect.end()); AA::A a(10); AA::A b(20); swap(a,b); return 0; }
Seule swap(a,b) utilise le swap définie dans le namespace.
Dans le lien que tu as posté de Sutter:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14 // Example 4(c): Overloading swap(). // class MyClass { public: void Swap( MyClass& ) throw(); // ... }; // NOTE: Not in namespace std. swap( MyClass& a, MyClass& b ) // throw() { a.Swap( b ); }
si je fait (dans le code précédent et un S majuscule dans la fonction de la classe)
visual me fait
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 swap ( A& a, A& b ) { // std::cout<<"AA::swap"<<std::endl; a.Swap(b); };
et si je faitspécificateur de type manquant - int est pris en compte par défaut.
la fonction n'est appelé que par swap(a,b) et jamais par le sort.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 void swap ( A& a, A& b ) { // std::cout<<"AA::swap"<<std::endl; a.Swap(b); };
Je doit bien m'être planté quelque part mais je ne voie pas ou...
Et si tu mets ceci dans AA::A:
Puis dans AA:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 private: friend bool operator<(A const& a, A const& b);
Edit: finalement, j'ai testé (avec gcc). Ca fonctionne:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 bool operator<(A const& a, A const& b) { return a.nb<b.nb; }
(désolé, l'indentation doit être merdique)
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 #include <algorithm> #include <iostream> #include <vector> #include <string> #include <iterator> namespace AA { class A { public: A(int a) :nb(a) { }; bool operator<(const A& a) { return nb<a.nb; } A& operator=(const A& a) { nb = a.nb; return (*this); } void swap(A& a) { std::swap(nb,a.nb); }; private: int nb; friend bool operator<(const A& a, const A& b); friend std::ostream& operator<<(std::ostream& o, A const& a); }; void swap ( A& a, A& b ) { std::cout<<"AA::swap"<<std::endl; a.swap(b); }; bool operator<(const A& a, const A& b) { return a.nb<b.nb; } std::ostream& operator<<(std::ostream& o, AA::A const& a) { return o << a.nb; } }//fin namespace int main(int argc, char** argv) { //mon vecteur a trier std::vector<AA::A> vect; //on remplie de n'importe quoi for(int i =0 ; i < 1000 ; ++i) vect.push_back(AA::A(rand())); //on fait le trie std::sort(vect.begin(),vect.end()); std::copy(vect.begin(), vect.end(), std::ostream_iterator<AA::A>(std::cout, ",")); AA::A a(10); AA::A b(20); swap(a,b); return 0; }
je voie pas trop ce que cela changerai... mais ça na rien changé.
Par contre sous gcc ça marche.
Si je regarde le code de sort, visual utilise std::swap alors que gcc utilse swap. C'est dans la définition de iter_swap
Donc ca expliquerai mon problème.
[edit]
Si je remplace std::swap par swap dans le fichier algorithm de visual, ça marche... Mais bon, je suis pas sur que c'est une solution...
Par défaut, c'est une très très très mauvaise idée que de vouloir aller modifier un fichier d'en-tête standard (ou de toute bibliothèque dont tu ne dispose pas explicitement le code source d'ailleurs )
Il ne faut pas oublier que, malgré que la bibliothèque standard soit en grande partie basée sur des template, il est possible d'avoir des dlls ou des en-têtes pré compilées de celle-ci (quand on compile gcc avec l'option --enable-shared, on obtient une dll stdc++ et une autre supc++), même si on se doute parfaitement que les parties implémentées par celles-ci ne peuvent forcément pas être prévues pour fonctionner avec n'importe quel type (sans doutes les types primitifs, les std::string et les différent I/Ostream ?)
Si tu modifie le fichier d'en-tête standard sans faire attention, va savoir quelles régressions tu risques d'occasionner en espérant résoudre un problème pouvant être considéré comme marginal
A méditer: La solution la plus simple est toujours la moins compliquée
Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
Compiler Gcc sous windows avec MinGW
Coder efficacement en C++ : dans les bacs le 17 février 2014
mon tout nouveau blog
Je me doutais que, venant de toi, il n'y avait pas énormément de risques que tu laisse le fichier d'en-tête ainsi modifié, mais je voulais surtout attirer l'attention de toute personne lisant cette discussion sur le fait que c'était une très mauvaise idée (des fois qu'il y ait un quidam quelconque qui puisse croire que c'était la solution à son problème )
Pour peu (je n'ai pas été vérifier) que la norme n'ait pas été très précise sur la manière de s'y prendre, ou qu'elle ait précisé que c'était défini par l'implémentation, ce n'est pas *forcément* surprenant...Je suis étonné que visual et gcc ont un comportement différent sur ce point...
Il faut aussi voir les "casseroles" tirées par l'historique des différents compilateurs sur le sujet...
Je rappelle quand même que, jusqu'à il n'y a que quelques années, microsoft était connu pour ne respecter les normes que de la manière qu'il voulait bien (non, je n'essaye pas de relancer un troll... toute allusion à cette dernière phrase sera supprimée "a vue" )
A méditer: La solution la plus simple est toujours la moins compliquée
Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
Compiler Gcc sous windows avec MinGW
Coder efficacement en C++ : dans les bacs le 17 février 2014
mon tout nouveau blog
Je viens de tester au travaille. Sous visual 2008 sp1 ça marche en faite.
La fonction iter_swap utilise bien swap.
Chez moi j'utilise visual 2008 express et c'est avec lui que ça ne marche pas
Il me semblais que la version express correspondait à visual 2008 sp1 pour la compilation.
J'ai pas le temps de chercher quel est l'etat actuel, d'autant plus que l'abandon des concepts a du avoir un effet important. Voir http://www.open-std.org/jtc1/sc22/wg...2001/n1296.asc pour C++98
Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager