我有模板功能,比方说,
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);
}
公共接口是仅采用向量引用的接口。我想隐藏另一个,实现,以便没有客户端代码可以做
mysort(vec, a, b, c);
创建一个类并使实现函数私有静态感觉不对,我尝试使用匿名命名空间,
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指令编译,但不能用合格的名称编译,以及是否有更好的方法来实现我想要的东西?
答案 0 :(得分: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)...
}
回答有关未命名的命名空间行为的问题:
未命名的命名空间(它们不被称为匿名命名空间)被命名有点奇怪 - 它们是未命名的,但编译器实际上为它生成了一个唯一的内部名称。您的示例等同于:
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)
,但您可以using namespace abc; mysort(vec, 1, 2, 3)
。
这是因为没有abc::mysort
个,只有abc::def::mysort
和abc::mysort
。当您声明实际abc::mysort
时,它会隐藏using namespace def
引入的内容。请注意,如果您注释掉1-param mysort
,您实际上可以说abc::mysort(vec, 1, 2, 3)
。
由于它已隐藏,因此对abc::mysort
的合格调用必须明确abc::mysort
,并且只能找到1-param版本。
但是,通过using namespace abc; mysort(vec, 1, 2, 3)
的无限制通话,它可以使用ADL查找匹配的任何可用功能。
答案 1 :(得分:0)
我做了一些测试,实际上,在更高版本的gcc(Ubuntu / Linaro 4.6.3-1ubuntu5)和-std = c ++ 0x中,它完全符合我的预期。
在主文件中,using指令或使用限定名称都不允许您在匿名命名空间内调用一个函数,该命名空间本身位于另一个命名空间内。
我认为原因是编译器确认了最新的标准,默认情况下,未命名的命名空间有内部链接。
在我看来,未命名的命名空间方法应该优于旧的“详细”命名空间实践。