Reputation:
I have template functions, say,
template<class T>
void mysort(std::vector<T>& vec)
{
size_t b, m, e,
...
mysort(vec, b, m, e);
}
template<class T>
void mysort(std::vector<T>& vec, size_t b, size_t m, size_t e)
{
size_t x, y, z;
...
mysort (vec, x, y, z);
}
The public interface is the one take only a vector reference. I would like to hide the other one, the implementation, so that no client code can do
mysort(vec, a, b, c);
It doesn't feel right to create a class and make the implementation function private static, I try to use the anonymous namespace,
namespace abc
{
namespace
{
template<class T>
void mysort(std::vector<T>& vec, size_t b, size_t m, size_t e)..
}
template<class T>
void mysort(std::vector<T>& vec)...
}
It helps, but not exactly a knockout...
#include "mysort.h"
int main()
{
...
abc::mysort(vec, a, b, c); // this won't compile, good
}
however if I change it to:
#include "mysort.h"
using namespace abc;
int main()
{
...
mysort(vec, a, b, c); // it compiles and runs!!
}
I am using gcc Ubuntu 4.4.3-4ubuntu5 on x86_64. can anyone explain why it compiles with using directive, but not with qualified names, and whether there is a better way to achieve what I want?
Upvotes: 4
Views: 165
Reputation:
I did some more testing, actually, in a later version gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) and -std=c++0x, it does exactly what I expected.
In the main file, neither the using directive or using the qualified name will allow you to call a function inside an anonymous namespace that itself is inside another namespace.
I think the reason is the compiler confirms the latest standard, which says an unnamed namespace has internal linkage by default.
It seems to me, the unnamed namespace approach should be preferred to the old "detail" namespace practice.
Upvotes: 0
Reputation: 29981
The common idiom for this is to create a "detail" namespace, which is intended only for internally-used code:
namespace abc
{
namespace detail
{
template<class T>
void mysort(std::vector<T>& vec, size_t b, size_t m, size_t e)..
}
template<class T>
void mysort(std::vector<T>& vec)...
}
To answer your question about the unnamed namespace behavior:
Unnamed namespaces (they're not called anonymous namespaces) are named a bit weird -- they're unnamed to you, but the compiler actually generates a unique internal name for it. Your example is equivalent to:
namespace abc
{
namespace def // lets say 'def' is unique.
{
template<class T>
void mysort(std::vector<T>& vec, size_t b, size_t m, size_t e)..
}
using namespace def;
template<class T>
void mysort(std::vector<T>& vec)...
}
You'll notice it behaves the same as your unnamed example: you can't do abc::mysort(vec, 1, 2, 3)
here, but you can using namespace abc; mysort(vec, 1, 2, 3)
.
This happens because there aren't two abc::mysort
s, only a abc::def::mysort
and abc::mysort
. When you declared an actual abc::mysort
, it hides the one brought in by using namespace def
. Note if you comment out the 1-param mysort
, you can actually say abc::mysort(vec, 1, 2, 3)
.
Because it was hidden, a qualified call to abc::mysort
must look at explicitly abc::mysort
, and only finds the 1-param version.
However, with an unqualified call via using namespace abc; mysort(vec, 1, 2, 3)
, it can use ADL to find any available function which matches.
Upvotes: 6