如何从客户端代码中隐藏模板化的非成员函数?

4 c++ templates namespaces linkage

我有模板功能,比方说,

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);
}
Run Code Online (Sandbox Code Playgroud)

公共接口是仅采用向量引用的接口.我想隐藏另一个,实现,以便没有客户端代码可以做

mysort(vec, a, b, c);
Run Code Online (Sandbox Code Playgroud)

创建一个类并使实现函数私有静态感觉不对,我尝试使用匿名命名空间,

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)...

}
Run Code Online (Sandbox Code Playgroud)

这有帮助,但不完全是淘汰赛......

#include "mysort.h"

int main()
{
    ...
    abc::mysort(vec, a, b, c); // this won't compile, good
}
Run Code Online (Sandbox Code Playgroud)

但是,如果我将其更改为:

#include "mysort.h"

using namespace abc;

int main()
{
    ...
    mysort(vec, a, b, c); // it compiles and runs!!
}
Run Code Online (Sandbox Code Playgroud)

我在x86_64上使用gcc Ubuntu 4.4.3-4ubuntu5.任何人都可以解释为什么它使用using指令编​​译,但不能使用合格的名称,以及是否有更好的方法来实现我想要的?

Cor*_*son 6

常见的习惯用法是创建一个"细节"命名空间,该命名空间仅用于内部使用的代码:

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)...

}
Run Code Online (Sandbox Code Playgroud)

要回答有关未命名的命名空间行为的问题:

未命名的命名空间(它们不被称为匿名命名空间)被命名有点奇怪 - 它们未命名给你,但编译器实际上为它生成了一个唯一的内部名称.你的例子相当于:

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)...

}
Run Code Online (Sandbox Code Playgroud)

您会注意到它的行为与您未命名的示例相同:您不能在abc::mysort(vec, 1, 2, 3)这里做,但您可以using namespace abc; mysort(vec, 1, 2, 3).

这是因为没有两个abc::mysorts,只有一个abc::def::mysortabc::mysort.当你宣布一个实际的abc::mysort,它隐藏了一个带来的using namespace def.请注意,如果您注释掉1-param mysort,您实际上可以说abc::mysort(vec, 1, 2, 3).

因为它是隐藏的,所以abc::mysort必须明确查看合格的调用abc::mysort,并且只能找到1-param版本.

但是,通过不合格的调用via using namespace abc; mysort(vec, 1, 2, 3),它可以使用ADL查找匹配的任何可用函数.