命名空间中 using 声明的范围
在 C++ 头文件中使用命名空间中的 using 声明是否安全(且正确),如下所示:
Is it safe (and correct) in a C++ header file to use the using declaration within a namespace as follows:
#include <boost/numeric/ublas/vector.hpp>
namespace MyNamespace {
using boost::numeric::ublas::vector;
vector MyFunc(vector in);
}
即使用 boost::numeric::ublas::vector"是否正确包含在 MyNamespace 块中,或者这会污染包含此标头的任何文件的名称空间?
I.e. is the "using boost::numeric::ublas::vector" properly contained within the MyNamespace block, or will this pollute the namespace of any file that includes this header?
推荐答案
不,这不安全 - 它不会污染另一个命名空间,但由于其他原因很危险:
No, it is not safe - it won't pollute another namespace, but it is dangerous for other reasons:
using
指令将通过您指定的名称将任何当前可见的内容导入您使用它的命名空间.虽然您的 using
仅对 MyNamespace
的用户可见,但来自外部"的其他内容将不可见.您的 using
声明将可见.
A using
directive will import anything that is currently visible by the name you specify into the namespace where you use it. While your using
will only be visible to users of MyNamespace
, other things from "outside" will be visible to your using
declaration.
那么在标题中使用时这有多危险?因为它将导入在声明时可见的内容,所以确切的行为将取决于您在声明之前包含的标头的顺序(从 boost::numeric::ublas::向量
).由于您无法真正控制在您的标头之前包含哪些标头(您也不应该这样做!标头应该是自给自足的!),这可能会导致非常奇怪的问题,您的函数会在一个编译单元中找到一个东西,而另一个在下一个.
So how is this dangerous when used in a header? Because it will import things that are visible at the point of the declaration, the exact behavior will depend on the order of headers you include before the declaration (There might be different things visible from boost::numeric::ublas::vector
). Since you cannot really control which headers are included before your header (nor should you be! headers should be self-sufficient!), this can lead to very strange problems where your function will find one thing in one compilation unit, and another in the next.
根据经验,using
声明只能在 之后使用 .cpp 文件中的所有内容.在C++ 编码标准"一书中也有一个关于这个确切问题的项目.Sutter 和 Alexandrescu(第 59 项).这是一个报价:
As a rule of thumb, using
declarations should only be used after all includes in a .cpp file. There's also an item on this exact issue in the book "C++ Coding Standards" by Sutter and Alexandrescu (Item 59). Here's a quote:
但这是一个常见的陷阱:许多人认为 using 在命名空间级别 (...) 发布的声明是安全的.他们不是.它们至少同样危险,而且以一种更微妙、更阴险的方式.
But here's the common trap: Many people think that using declarations issued at namespace level (...) are safe. They are not. They are at least as dangerous, and in a subtler and more insidious way.
即使您使用的名称
不太可能不存在于其他任何地方(可能就是这里的情况),事情可能会变得丑陋:在标题中,所有声明都应该是 完全合格.这很痛苦,但否则,可能会发生奇怪的事情.
Even when it's unlikely that the name you are using
doesn't exist anywhere else (as is probably the case here), things can get ugly: In a header, all declarations should be fully qualified. This is pain, but otherwise, strange things can happen.
另请参阅迁移到命名空间,使用声明和命名空间别名 和 命名空间命名 示例和深入描述的问题.
Also see Migrating to Namespaces, Using-declarations and namespace aliases and Namespace Naming for examples and the problem described in-depth.
相关文章