2008-10-21 113 views
80

我在C++中使用'using'声明将std :: string和std :: vector添加到本地命名空间(以节省键入不必要的'std ::'s)。C++中“using”声明的范围是什么?

using std::string; 
using std::vector; 

class Foo { /*...*/ }; 

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

+17

只是为了防止其他答案在这里清楚: - **不要在包含文件/头文件中的文件范围使用`using`声明(或`using`指令)**这将为标题的用户造成头痛。 – 2008-10-21 19:07:07

+0

事实上,不要在头文件**中使用`using`声明(即*指令*),即使在命名空间内也是如此!*请参阅[在命名空间内使用声明的范围](http:/ /stackoverflow.com/q/6175705/2025416)以解决这些问题。 – 2016-05-22 15:07:04

回答

53

当您在C++中包含头文件时,它会将头文件的全部内容放入您将其包含在源文件中的位置。因此,包含具有using声明的文件具有将using声明放在包含该头文件的每个文件顶部的效果。

+43

...这通常是一件坏事。 – Catskul 2011-02-16 05:25:13

+13

但是,如果你把`using`声明放在`namespace`里面,它就局限于那个命名空间的范围,所以一般都可以(对你的特定需求和风格有通常的注意事项)。 – Zero 2012-12-04 23:09:39

+1

......但是如果你确实在命名空间中使用了内部命令空间,请确保你没有试图绕过通常是个坏主意的东西,就像你不能在外部命名空间Y中声明的类方法一样。其他命名空间X,只是这样你才可以在本地使用命名空间X.这就是为什么我们首先使用namespace :: resolvers。如果它的键入问题很大,或者是一个宏(它可能很容易导致代码味道)或者更好,将它分离到它自己的源代码.cpp中,您将只在那里使用名称空间。 – osirisgothra 2014-01-17 17:29:14

5

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

您还可以将using语句放在类中,在这种情况下,它仅适用于该类。

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

+0

请注意,类中的`using`声明的行为方式与类之外的行为不同 - 例如,您不能使用它将`cout`而不是`std :: cout`带入类的范围。 – Zero 2012-12-04 23:07:32

2

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

86

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

您可以限制using声明的范围:

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

我从来没有想过我可以在一个函数内使用它! – Agostino 2015-03-04 22:50:35

4

范围是什么范围使用的声明是在

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

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

44

using语句的范围取决于它位于代码:

  • 放置在文件的顶部,它在整个这个文件的范围。
  • 如果这是一个头文件,它将在包含该头的所有文件中都有作用域。在一般情况下,这是“不是一个好主意”,因为它可以有意想不到的副作用
  • 否则使用语句包含它从它发生在块的结束点块内的范围。如果它放在方法中,它将在该方法中有作用域。如果它放在类定义中,它将在该类中有范围。
1

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

书写using std::string永远不会。在你自己的头文件中写入using ImplementationDetail::Foo,当头文件声明ImplementationDetail :: Foo可以正常时,如果使用声明发生在你的名字空间中,则更是如此。例如。

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