In C++ you specify internal linkage by wrapping your class and function definitions inside an anonymous namespace. You can also explicitly instantiate templates, but to be standards conforming any explicit instantiations of the templates must occur in the same namespace. AFAICT this should compile, but GCC fails on it:
namespace foo {
template<class T>
class bar {};
}
using namespace foo;
namespace {
template class bar<int>;
}
int main()
{
return 0;
}
With the error:
namespace_test.cpp:11: error: explicit instantiation of 'class bar<int>' in namespace '<unnamed>' (which does not enclose namespace 'foo')
Which is interesting because the anonymous namespace should just be specifying linkage, not really functioning as a namespace, and the global namespace definitely encloses foo, since it encloses every namespace. But even this doesn't work!:
template<class T>
class bar {};
using namespace foo;
namespace {
template class bar<int>;
}
int main()
{
return 0;
}
Which fails with the same error, just listing the global namespace instead:
namespace_test.cpp:11: error: explicit instantiation of 'class bar<int>' in namespace '<unnamed>' (which does not enclose namespace '::')
:/
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.
Namespace is a feature added in C++ and is not present in C. A namespace is a declarative region that provides a scope to the identifiers (names of functions, variables or other user-defined data types) inside it. Multiple namespace blocks with the same name are allowed.
Inside a namespace, no two classes can have the same name.
There are three main namespaces. The ISO C++ standards specify that "all library entities are defined within namespace std." This includes namespaces nested within namespace std , such as namespace std::chrono . Specified by the C++ ABI.
An anonymous namespace is logically equivalent to
namespace _TU_specific_unique_generated_name
{
// ...
}
using namespace _TU_specific_unique_generated_name;
A namespace, anonymous or otherwise, has no effect on the linkage of its members. In particular members of an anonymous namespace do not magically get internal linkage.
First: You are explicitly instantiating a class template, you are not defining a new class template. What
template class bar<int>;
says is "please instantiate the class template bar for type int here". You cannot do that in another namespace, just as you cannot partially specialise a class template in another namespace. In particular, the template to be explicitly instantiated must have been defined, and in your example, there's no (anonymous namespace)::bar<>, only foo::bar<>.
Second: The anonymous namespace is a real namespace (it's distinct in every translation unit, though). It also doesn't magically change linkage. Everything declared inside namespace {} has still the default linkage, just like at any other namespace scope. IIRC, it was even added to allow for translation unit-private, yet external-linkage objects.
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