Inline espaces de noms sont une bibliothèque fonctionnalité de gestion des versions semblable à symbole de gestion des versions, mais la mise en œuvre purement le C++11 niveau (ie. multi-plateforme), au lieu d'être une caractéristique spécifique d'un fichier binaire exécutable format (ie. plate-forme spécifique).
C'est un mécanisme par lequel une bibliothèque d'auteur peuvent faire d'un espace de noms imbriqué regarder et agir comme si tous ses déclarations ont été dans les environs de l'espace de noms (inline espaces de noms peuvent être imbriquées, donc "plus imbriquée" noms s'infiltrer jusqu'à la première non en ligne de l'espace de noms et d'examiner et d'agir comme si leurs déclarations dans les espaces de noms entre les deux, trop).
Considérez, par exemple, la STL mise en œuvre de l' vector
. Si nous avions inline espaces de noms à partir du début de C++, puis en C++98 l'en-tête <vector>
pourrait ressembler à ceci:
namespace std {
#if __cplusplus < 1997L // pre-standard C++
inline
#endif
namespace pre_cxx_1997 {
template <class T> __vector_impl; // implementation class
template <class T> // e.g. w/o allocator argument
class vector : __vector_impl<T> { // private inheritance
// ...
};
}
#if __cplusplus >= 1997L // C++98/03 or later
// (ifdef'ed out b/c it probably uses new language
// features that a pre-C++98 compiler would choke on)
# if __cplusplus == 1997L // C++98/03
inline
# endif
namespace cxx_1997 {
// std::vector now has an allocator argument
template <class T, class Alloc=std::allocator<T> >
class vector : pre_cxx_1997::__vector_impl<T> { // the old impl is still good
// ...
};
// and vector<bool> is special:
template <class Alloc=std::allocator<bool> >
class vector<bool> {
// ...
};
};
#endif // C++98/03 or later
} // namespace std
Selon la valeur de __cplusplus
, soit l'un ou l'autre vector
mise en œuvre est choisi. Si votre base de code a été écrit en pré-C++98 fois, et que vous trouvez que le C++98 version de vector
est à l'origine de la difficulté pour vous lorsque vous mettez à niveau votre compilateur, "tous", vous avez à faire est de trouver les références à std::vector
dans votre base de code et de les remplacer par std::pre_cxx_1997::vector
.
Venir la prochaine norme, et la STL vendeur ne fait que répéter la procédure de nouveau, l'introduction d'un nouvel espace de noms pour std::vector
avec emplace_back
de soutien (ce qui nécessite de C++11) et l'in-lining que l'on iff __cplusplus == 201103L
.
OK, alors pourquoi ai-je besoin d'une nouvelle fonctionnalité pour cela? Je peux déjà faire ce qui suit pour avoir le même effet, non?
namespace std {
namespace pre_cxx_1997 {
// ...
}
#if __cplusplus < 1997L // pre-standard C++
using namespace pre_cxx_1997;
#endif
#if __cplusplus >= 1997L // C++98/03 or later
// (ifdef'ed out b/c it probably uses new language
// features that a pre-C++98 compiler would choke on)
namespace cxx_1997 {
// ...
};
# if __cplusplus == 1997L // C++98/03
using namespace cxx_1997;
# endif
#endif // C++98/03 or later
} // namespace std
Selon la valeur de __cplusplus
,- je obtenir soit l'un ou l'autre des implémentations.
Et vous auriez presque correct.
Considérez les points suivants valide en C++98 code de l'utilisateur (il a été autorisé à se spécialiser entièrement des modèles qui vivent dans l'espace de noms std
en C++98, déjà):
// I don't trust my STL vendor to do this optimisation, so force these
// specializations myself:
namespace std {
template <>
class vector<MyType> : my_special_vector<MyType> {
// ...
};
template <>
class vector<MyOtherType> : my_special_vector<MyOtherType> {
// ...
};
// ...etc...
} // namespace std
C'est parfaitement valide code si l'utilisateur fournit son propre mise en œuvre d'un vecteur d'un ensemble de type où apparemment elle sait une application plus efficace que l'on retrouve dans (sa copie de la STL).
Mais: Quand spécialisée d'un modèle, vous devez le faire dans l'espace de noms, il a été déclaré dans. La Norme dit qu' vector
est déclaré dans l'espace de noms std
, de sorte que lorsque l'utilisateur s'attend légitimement à se spécialiser le type.
Ce code fonctionne avec un non versionnés espace de noms std
, ou avec le C++11 inline fonctionnalité des espaces de noms, mais pas avec la gestion des versions truc qui utilisaient using namespace <nested>
, parce que expose le détail de l'implémentation que la véritable espace de noms dans lequel vector
a été défini n'a pas été std
directement.
Il y a d'autres trous par lesquels vous pourriez détecter le sous-espace de noms (voir les commentaires ci-dessous), mais inline espaces de noms les brancher tous. Et c'est tout là est à lui. Très utiles pour l'avenir, mais autant que je sache, le Standard ne veut pas prescrire inline noms d'espaces de noms pour sa propre bibliothèque standard (j'aimerais avoir tort sur ce point, tout de même), de sorte qu'il peut être utilisé uniquement pour les bibliothèques de tiers, pas de la norme elle-même (à moins que les éditeurs de compilateurs d'accord sur un schéma de nommage).