首页 > 解决方案 > “使用命名空间”子句在什么范围内有效?

问题描述

我曾经听过/读过(参考已经滑倒了我的脑海;无法引用它)“ 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上面的第一个变体中尝试的内容。

请注意:根据 Stack Overflow Q&A 的说明,除了显式使用--std=c++11编译器标志外,使用的编译器版本远高于不会遇到此错误的最低要求(没有显式使用编译器标志)。--std=c++11

在这种情况下,这个编译器错误是什么意思(如果与我的上述理解不同)(我的用法与前面提到的两个 Stack Overflow Q&A 中的用法不同)。

一般来说:“使用命名空间”指令在什么范围内有效

标签: c++compiler-errorsnamespacesusingusing-directives

解决方案


来自cppreference.com

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

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


推荐阅读