是否可以将函数(或其他符号)导入命名空间但不能导出?例如,我想将std::string
导入当前名称空间,但我不希望current::string
可见。
namespace current {
using std::string;
string func();
}
current::string
应该不是问题。
用例只是减少输入(并经常忘记使用std::string
等),并使代码更易读,而不会导致所有名称空间语法混乱。
答案 0 :(得分:5)
是否可以将函数(或其他符号)导入命名空间但不能导出?
不。
using
指令将引入所有引用您在声明中使用的名称的符号,并且current
的用户将看到它们,就像它们实际上是在名称空间本身中声明的一样。
该标准的相关部分在[namespace.udir]/1
中:
using伪指令指定可以在使用伪指令之后出现using伪指令的范围内使用指定命名空间中的名称。在进行非限定名称查找(6.4.1)期间,这些名称看起来好像是在包含使用指令和指定名称空间的最近的封闭名称空间中声明的一样。 [注意:在本文中,“包含”是指“直接或间接包含”。 —尾注]
答案 1 :(得分:2)
“计算机科学中的所有问题都可以通过另一种间接解决方案来解决” – David Wheeler
在这种情况下,绝对是这样:
namespace current {
namespace impl {
using std::string;
string func();
}
using impl::func;
}
诚然,有费用:
current
导出的每个单个类型或函数。 using namespace
。 (只需将其视为一项功能,因为它可以使您的API的内容刻意而不是巧合。)func
的名称会在我所知道的所有实现中更改)顺便说一句,名称空间名称current
表明您可能还考虑了版本控制。这两种方法可以很好地结合起来,例如:
namespace _v1 {
namespace impl {
int func();
}
// Exports
using impl::func;
}
namespace _v2 {
namespace impl {
using std::string;
string func();
}
// Exports
using impl::func;
}
namespace current = _v2;
答案 2 :(得分:0)
如果不导出函数的返回值,则不能导出函数func
。
问题应该是,func
在给定名称空间中有意义的名称是什么。如果current::string
没有意义,那么string
可能是func
结果的坏名字吗?它返回什么?例如一些代码? current::code
更好吗?然后在string
中将code
重命名为current
。
namespace current {
using code = std::string;
code func();
}
尝试尽可能减少打字不是一个好主意。否则,最好的办法是尽可能使用短名称:
namespace c {
using s = std::string;
s f();
}
这将使它的使用非常隐秘。
答案 3 :(得分:-1)
否,您的代码是错误的做法。尽管您的特定示例std::string
可能不会引起冲突,但未命名的查找可能会将对其他string
的定义的引用拉到命名空间范围的之外,从而可能导致重新声明错误或使用与您期望的名称不同的名称进行未命名的查找。例如,可能会发生这种情况:a)您或您代码中的其他人使用的名称与库冲突(例如distance
),b)库使用的名称冲突(例如Boost),c)或其他翻译单元从外部作用域引入了不同的名称,从而导致相似的代码具有完全不同的行为。
要么始终完全限定您的声明,要么至少使用using ::std::string
。