In standard library, I found that namespace std
is declared as a macro.
#define _STD_BEGIN namespace std {
#define _STD_END }
- Is this a best practice when using namespaces?
- The macro is declared in
Microsoft Visual Studio 9.0\VC\include\yvals.h
. But I couldn't find the STL files including this. If it is not included, how 开发者_运维百科it can be used?
Any thoughts..?
Probably not a best practice as it can be difficult to read compared to a vanilla namespace
declaration. That said, remember rules don't always apply universally, and I'm sure there is some scenario where a macro might clean things up considerably.
"But I couldn't find the STL files including this. If it is not included, how it can be used?".
All files that use this macro include yvals.h
somehow. For example <vector>
includes <memory>
, which includes <iterator>
, which includes <xutility>
, which includes <climits>
, which includes <yvals.h>
. The chain may be deep, but it does include it it some point.
And I want to clarify, this only applies to this particular implementation of the standard library; this is in no way standardized.
- In general No. The macros were probably used at the time when namespaces were not implemented by some compilers, or for compatibity with specific platforms.
- No idea. The file would probably be included by some other file that was included into the STL file.
One approach that I saw in a library that I recently used was:
BEGIN_NAMESPACE_XXX()
where XXX is the number of namespace levels for example:
BEGIN_NAMESPACE_3(ns1, ns1, ns3)
would take three arguments and expand to
namespace ns1 {
namespace ns2 {
namespace ns2 {
and a matching END_NAMESPACE_3
would expand to
}
}
}
(I have added the newlines and indentation for clarity's sake only)
I imagine the only reason to do this is if you want to make it easy to change the namespace used by your application / library, or disable namespaces altogether for compatibility reasons.
I could see doing this for the C libraries that are included in C++ by reference (eg., the header that C calls string.h
and that C++ calls cstring
). In that case, the macro definition would depend on an #ifdef _c_plus_plus
.
I wouldn't do it in general. I can't think of any compiler worth using that doesn't support namespaces, exceptions, templates or other "modern" C++ features (modern is in quotes because these features were added in the mid to late '90s). In fact, by my definition, compilers are only worth using if they offer good support for their respective language. This isn't a language issue; it's a simple case of "if I chose language X, I'd prefer to use it as it exists today, not as it existed a decade or two ago." I've never understood why some projects spend time trying to support pre-ANSI C compilers, for instance.
精彩评论