“ using名称空间”子句在什么范围内有效?

时间:2019-12-12 21:49:40

标签: c++ compiler-errors namespaces using using-directives

我曾经听过/读过(我的提法引起了我的注意;无法引用)“ using namespace”子句在任何范围内均有效,但在类范围内似乎无效:

// main.cpp

#include <iostream>

namespace foo
{
  void func() { std::cout << __FUNCTION__ << std::endl; }
};

class Foo
{
using namespace foo;

  public:
    Foo() { func(); }
};

int main( int argc, char* argv[] )
{
  Foo f;
}

$ g++ --version
g++ (GCC) 8.3.1 20190223 (Red Hat 8.3.1-2)
Copyright (C) 2018 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ g++ -g ./main.cpp 
./main.cpp:12:7: error: expected nested-name-specifier before 'namespace'
 using namespace foo;
       ^~~~~~~~~
./main.cpp: In constructor 'Foo::Foo()':
./main.cpp:15:13: error: 'func' was not declared in this scope
     Foo() { func(); }
             ^~~~
./main.cpp:15:13: note: suggested alternative:
./main.cpp:7:8: note:   'foo::func'
   void func() { std::cout << __FUNCTION__ << std::endl; }
        ^~~~
$
$ g++ --std=c++11 -g ./main.cpp 
./main.cpp:12:7: error: expected nested-name-specifier before 'namespace'
 using namespace foo;
       ^~~~~~~~~
./main.cpp: In constructor 'Foo::Foo()':
./main.cpp:15:13: error: 'func' was not declared in this scope
     Foo() { func(); }
             ^~~~
./main.cpp:15:13: note: suggested alternative:
./main.cpp:7:8: note:   'foo::func'
   void func() { std::cout << __FUNCTION__ << std::endl; }
        ^~~~

class Foo的以下变体导致相同的编译器错误:

class Foo
{
using namespace ::foo;

  public:
    Foo()
    {
      func();
    }
};

class Foo的以下变体不会导致编译器错误或警告:

class Foo
{
  public:
    Foo()
    {
      using namespace foo;
      func();
    }
};

class Foo
{
  public:
    Foo()
    {
      foo::func();
    }
};

基于阅读thisthis之类的帖子,我对编译器错误的理解(不正确?)是该错误本质上要求对使用的名称空间进行完全范围界定,即我在上面class Foo的第一个版本。

请注意:除了显式使用--std=c++11编译器标志之外,使用的编译器版本还远远高于不遇到此错误的最低要求(未显式使用--std=c++11编译器标志) ,根据著名的堆栈溢出问答。

此编译器错误是什么意思(如果与我上述理解有所不同)在这种情况下?(我的用法与上述两个堆栈溢出中的用法不同)问与答)。

通常:在什么范围内,“使用命名空间”指令有效

1 个答案:

答案 0 :(得分:2)

来自cppreference.com

  

仅在命名空间范围和块范围内允许使用指令。

因此,您可以在名称空间(包括全局名称空间)或代码块内使用它们。类声明都不是。