How to hide a template non-member function from client code?

I have a template function, let's 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 open interface is the only vector directory. I would like to hide another implementation so that client code cannot

 mysort(vec, a, b, c); 

It is incorrect to create a class and make the function implement private static, I'm trying to use an 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 quite by 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 using the directive, but not with qualified names, and is there a better way to achieve what I want?

+4
source share
2 answers

A common idiom for this is to create a namespace for the "part", which is intended only for internal 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 unnamed namespace behavior:

Namespaces (they are not called anonymous namespaces) are called a little strange - they are not named for you, but the compiler does generate a unique internal name for it. Your example is equivalent:

 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 will notice that it behaves the same as your unnamed example: here you cannot do abc::mysort(vec, 1, 2, 3) , but you can using namespace abc; mysort(vec, 1, 2, 3) using namespace abc; mysort(vec, 1, 2, 3) .

This is because there are no two abc::mysort s, only a abc::def::mysort and abc::mysort . When you declared the actual abc::mysort , it hides the one that was added using namespace def . Note that if you comment out 1-param mysort , you can say abc::mysort(vec, 1, 2, 3) .

Since it was hidden, a qualified call to abc::mysort must explicitly specify abc::mysort and only finds a version with 1 parameter.

However, if an unqualified call is made using namespace abc; mysort(vec, 1, 2, 3) using namespace abc; mysort(vec, 1, 2, 3) it can use ADL to search for any available function that matches.

+6
source

I did some more tests, in fact, in a later version of 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 nor the use of a qualified name allows you to call a function inside an anonymous namespace that is inside another namespace.

I think the reason is that the compiler confirms the latest standard, which says that by default the unnamed namespace has an internal relationship.

It seems to me that an unnamed approach to namespace should be preferred to the old practice of "namespace".

0
source

All Articles