Bonjour,
le problème me semble si classique que j'imagine qu'il a déjà été rencontré de nombreuses fois, pourtant je n'en ai trouvé aucune réponse satisfaisante, ni ici (faq et posts précédents) ni ailleurs sur le web.
Je souhaite définir un patron de classe dont l'essentiel est présenté ici :
Les définitions des fonctions et opérateurs membres et amis doivent être placées à l'extérieur pour des raisons de lisibilité de l'interface.
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 template<typename T> class foo { public: typedef T value_type; typedef T *iterator; typedef const T *const_iterator; typedef T &reference; typedef const T &const_reference; typedef size_t size_type; typedef foo self; template <typename Iter_T> void copy(Iter_T first, Iter_T last); iterator begin(); iterator end(); const_iterator begin() const; const_iterator end() const; reference operator[](size_type n); const_reference operator[](size_type n) const; static size_type size(); // friend operators friend self operator+ (self x, const self &y); friend self operator- (self x, const self &y); friend self operator+ (self x, value_type y); friend self operator- (self x, value_type y); friend self operator* (self x, value_type y); friend self operator/ (self x, value_type y); friend self operator% (self x, value_type y); };
A priori, la déclaration de classe précédente est anodine et sans surprise (cf. par exemple le C++ Cookbook de chez O'Reilly qui propose une classe kvector très similaire), l'ennui c'est qu'elle ne passe la compilation, en tout cas sous g++ 3.4.3 et icc 9.0 (de Intel) disponible sur ma station de travail (Linux). Une recherche sur le web me porte à croire que la version actuelle du Comeau (considéré comme très conforme au standard) ne l'accepte pas non plus.
Tous exigent des chevrons <> après le nom des opérateurs (au passage, ces chevrons ne sont pas spécifiés dans l'exemple C.13.2 du Stroustrup sur les opérateurs amis de classes templates)
Avec g++ 3.4.3 :
Avec icc 9.0 :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 ./foo.h:51: warning: friend declaration `foo<T, N> operator+(foo<T, N>, const foo<T, N>&)' declares a non-template function ./foo.h:51: warning: (if this is not what you intended, make sure the function template has already been declared and add <> after the function name here) -Wno-non-template-friend disables this warning
Qu'a cela ne tienne, rajoutons les chevrons demandés :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 warning #1624: "foo<T, N>::self operator+(foo<T, N>::self, const foo<T, N>::self &)" declares a non-template function -- add <> to refer to a template instance friend self operator+ (self x, const self &y);
friend self operator+ <>(self x, const self &y);
Voici maintenant les réactions des compilateurs :
Avec g++ 3.2.3 :
cela compile
Avec g++ 3.4.3 et supérieur (au moins jusqu'à la version 4.0) :
Avec icc 9.0 :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 ./foo.h:51: error: declaration of `operator+' as non-function ./foo.h:51: error: expected `;' before '<' token
Ma connaissance du standard C++ actuel étant très fragmentaire, les messages précédents me plongent dans un abime de perplexité. De plus, j'ai du mal à imaginer des bogues de compilateur, sur 2 compilateurs différents et plusieurs versions du même compilateur (inutile de poster pour suggérer cela, sauf preuves ou commentaires sérieux à l'appui).
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 ./foo.h(51): error: operator+ is not a template friend self operator+ <>(self x, const self &y); ^ detected during instantiation of class "foo<Value_T, N> [with Value_T=int, N=4U]" at line 9 of "./test_foo.cpp"
Je recherche si possible une solution portable à ce problème.
Merci d'avance de vos interventions.
Partager