[英]How to hide a templated non-member function from client's code?
我有模板功能,例如,
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。 谁能解释为什么使用指令而不是限定名称进行编译,以及是否有更好的方法来实现我想要的?
常见的用法是创建一个“详细”名称空间,该名称空间仅用于内部使用的代码:
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)
,但可以using namespace 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)
进行不合格的调用using namespace abc; mysort(vec, 1, 2, 3)
using namespace abc; mysort(vec, 1, 2, 3)
,它可以使用ADL查找匹配的任何可用函数。
实际上,我在更高版本的gcc(Ubuntu / Linaro 4.6.3-1ubuntu5)和-std = c ++ 0x中进行了更多测试,它确实符合我的预期。
在主文件中,using指令或使用限定名称都不允许您在本身位于另一个名称空间内的匿名名称空间内调用函数。
我认为原因是编译器确认了最新标准,即未命名的命名空间默认具有内部链接。
在我看来,未命名的命名空间方法应该比旧的“详细”命名空间做法更可取。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.