I. Problèmes▲
I-A. Question Junior▲
Les déclarations anticipées sont des outils très utiles. Dans ce cas, elles ne fonctionnent pas comme attendu par le développeur. Pourquoi les lignes marquées sont-elles des erreurs ?
// file f.h
#ifndef XXX_F_H_
#define XXX_F_H_
class
ostream; // erreur
class
string; // erreur
string f( const
ostream&
);
#endif
I-B. Question Guru▲
Sans inclure aucun autre fichier, pouvez-vous écrire les déclarations anticipées correctes pour ostream et string ci-dessus ?
II. Solutions▲
II-A. Question Junior▲
Les déclarations anticipées sont des outils très utiles. Dans ce cas, elles ne fonctionnent pas comme attendu par le développeur. Pourquoi les lignes marquées sont-elles des erreurs ?
Malheureusement, vous ne pouvez pas déclarer par anticipation ostream et string de cette façon, parce que ce ne sont pas des classes... ce sont des typedefs de template.
(C'est vrai, autrefois vous déclariez par anticipation ostream et string de cette façon, mais c'était il y a plusieurs années et ce n'est plus possible en C++ standard.)
II-B. Question Guru▲
Sans inclure aucun autre fichier, pouvez-vous écrire les déclarations anticipées correctes pour ostream et string ci-dessus ?
Malheureusement, la réponse est qu'il n'y a pas de façon standard ni portable de le faire. La norme dit :
Ajouter des déclarations ou des définitions à l'espace de nom std ou à des espaces de nom au sein de l'espace de nom std n'est pas défini pour un programme C++, sauf spécifié autrement.
Entre autres choses, cela permet aux vendeurs de compilateur de fournir des implémentations de la bibliothèque standard qui ont davantage de paramètres template pour les templates de bibliothèque que ce que la norme exige (convenablement paramétrés par défaut, bien sûr, pour rester compatible).
Le mieux que vous puissiez faire (ce qui n'est pas une solution au problème "sans inclure aucun autre fichier") est ceci :
#include
<iosfwd>
#include
<string>
L'en-tête iosfwd contient bona fide une déclaration anticipée. Pas l'en-tête string. C'est tout ce que vous pouvez faire qui soit encore pratique. Heureusement, faire une déclaration anticipée de string et ostream n'est pas un gros problème en pratique, car ces lignes sont généralement courtes et largement utilisées. Cela vaut aussi pour la plupart des en-têtes standards. Toutefois, faites attention aux pièges et résistez à la tentation de lancer des templates à déclaration anticipée ? ni quoi que ce soit d'autre ? appartenant à l'espace de noms std... c'est réservé aux éditeurs de compilateurs et de bibliothèque et à eux seuls.
III. Remerciements▲
Cet article est une traduction par l'équipe de la rubrique C++ de l'article de Herb Sutter publié sur Guru of the Week. Vous pouvez retrouver cet article dans sa version originale sur le site de Guru of the Week : Forward DeclarationsForward Declarations.
Merci à Luc Hermitte pour sa relecture technique, à ClaudeLELOUP, à Gurdil le nain et à jacques_jean pour leur relecture orthographique.