How to hide a templated non-member function from client's code?
c++, linkage, namespaces, templates
Solution
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.
Problem
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?