C ++中“using”声明的范围是什么?

我在C ++中使用'using'声明将std :: string和std :: vector添加到本地名称空间(以节省不必要的input“std ::”)。

using std::string; using std::vector; class Foo { /*...*/ }; 

这个声明的范围是什么? 如果我在标题中这样做,它会注入这些“使用”声明到每个包含头文件的cpp文件吗?

当你在C ++中包含一个头文件的时候,它会把头文件的全部内容放到你包含在源文件中的位置上。 因此,包含具有using声明的文件与using声明放在包含该头文件的每个文件顶部的效果完全相同。

头文件没有什么特别的地方可以保留using声明。 编译甚至开始之前,这是一个简单的文本replace。

您可以将using声明限制为一个范围:

 void myFunction() { using namespace std; // only applies to the function's scope vector<int> myVector; } 

使用声明的范围取决于它在代码中的位置:

  • 放置在一个文件的顶部,它在整个文件的范围内。
  • 如果这是一个头文件,它将在包含该头的所有文件中有作用域。 一般来说,这是“ 不是一个好主意 ”,因为它可能会有意想不到的副作用
  • 否则, 使用语句在包含它的块的范围内从其出现的点到块的结尾。 如果它放在方法中,它将在该方法中有作用域。 如果放在类定义中,它将在该类中有范围。

在引用的情况下,文件(“翻译单位”),这意味着是,包括它的每个文件。

你也可以把这个using语句放在类里面,在这种情况下,这个类只是有效的。

通常,如果您需要在标题中指定一个名称空间,通常最好是对所有必需的标识符进行完全限定。

范围是使用声明所在的范围。

如果这是全球范围,那么它将在全球范围内。 如果它位于头文件的全局范围内,则它将位于包含头的每个源文件的全局范围内。

所以,一般的build议是避免在全局范围的头文件中使用声明

那是对的。 范围是使用using声明的模块。 如果模块包含的任何头文件都using声明,则这些声明的范围将是该模块以及包含相同头文件的任何其他模块。

当他们说“不”时,有几条评论是不合格的。 这太严厉了,但你必须明白什么时候可以。

using std::string写入永远不会。 在你自己的头文件中using ImplementationDetail::Foo进行编写时,如果头文件声明了ImplementationDetail :: Foo,那么如果使用声明发生在你的名字空间中的话。 例如

 namespace MyNS { namespace ImplementationDetail { int Foo; } using ImplementationDetail::Foo; }