Someone asserted on SO today that you should never use anonymous namespaces in header files. Normally this is correct, but I seem to remember once someone told me that one of the standard libraries uses anonymous namespaces in header files to perform some sort of initialization.
Am I remembering correctly? Can someone fill in the details?
An anonymous namespace makes the enclosed variables, functions, classes, etc. available only inside that file. In your example it's a way to avoid global variables. There is no runtime or compile time performance difference.
Code in header files should always use the fully qualified namespace name. The following example shows a namespace declaration and three ways that code outside the namespace can accesses their members.
Do not define an unnamed namespace in a header file. When an unnamed namespace is defined in a header file, it can lead to surprising results. Due to default internal linkage, each translation unit will define its own unique instance of members of the unnamed namespace that are ODR-used within that translation unit.
Since you can't put a namespace using statement at the top level of the header file, you must use a fully qualified name for Standard Library classes or objects in the header file. Thus, expect to see and write lots of std::string, std::cout, std::ostream, etc. in header files.
The only situation in which a nameless namespace in header can be useful is when you want to distribute code as header files only. For example, a large standalone subset of Boost is purely headers.
The token ignore
for tuples, mentioned in another answer is one example, the _1
, _2
etc. bind placeholders are others.
I don't see any point in putting an anonymous namespace into a header file. I've grepped the standard and the libstdc++ headers, found no anonymous namespaces apart of one in the tuple
header (C++1x stuff):
// A class (and instance) which can be used in 'tie' when an element // of a tuple is not required struct _Swallow_assign { template<class _Tp> _Swallow_assign& operator=(const _Tp&) { return *this; } }; // TODO: Put this in some kind of shared file. namespace { _Swallow_assign ignore; }; // anonymous namespace
This is so you can do
std::tie(a, std::ignore, b) = some_tuple;
elements of the some_tuple are assigned the variables at the left side (see here), a similar technique is used for this iterator. The second element is ignored.
But as they say, it should be put into a .cpp file and the one instance should be shared by all users. They would put a declaration of it into the header like this then:
extern _Swallow_assign ignore;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With