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

标签 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);
}

公共(public)接口(interface)是一个只接受 vector 引用的接口(interface)。我想隐藏另一个,即实现,这样就没有客户端代码可以做

mysort(vec, a, b, c);

创建一个类,实现函数private static感觉不对,我尝试使用匿名命名空间,

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

}

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

#include "mysort.h"

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

但是如果我把它改成:

#include "mysort.h"

using namespace abc;

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

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

最佳答案

这方面的常用习惯是创建一个“详细信息”命名空间,它仅用于内部使用的代码:

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

}

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

未命名的命名空间(它们不称为匿名命名空间)的命名有点奇怪——它们对你来说是未命名的,但编译器实际上为它生成了一个唯一的内部名称。您的示例等效于:

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

}

您会注意到它的行为与您未命名的示例相同:您不能在此处执行 abc::mysort(vec, 1, 2, 3),但您可以使用命名空间abc; mysort(vec, 1, 2, 3).

发生这种情况是因为没有两个 abc::mysort,只有一个 abc::def::mysortabc::mysort。当您声明一个实际的 abc::mysort 时,它会隐藏通过 using namespace def 引入的那个。请注意,如果您注释掉 1 参数 mysort,您实际上可以说 abc::mysort(vec, 1, 2, 3)

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

但是,通过 using namespace abc 进行非限定调用; mysort(vec, 1, 2, 3),它可以使用 ADL 找到匹配的任何可用函数。

关于c++ - 如何从客户端代码中隐藏模板化的非成员函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14060432/

相关文章:

c++ - Boost 程序选项 - 从函数结果传递 arg 名称

c++ - 通过 C++ 模板访问不同的数据

Android ksoap2 命名空间前缀

c++ - 你如何在 WxWidgets 中显示方程式的答案?

c++ - 在 gcc 4.8 中获取 operator<< 的地址失败

c++ - C++ 中的组模板参数

c++ - 模板推导/类型转换错误

c++ - 在我自己的命名空间中定义 size_t 会产生歧义或其他错误吗?

c++ - C++ 命名空间的奇怪行为

c++ - C++ 中的赋值运算符返回右值还是左值?