C++ C+中的嵌套名称空间+;

C++ C+中的嵌套名称空间+;,c++,namespaces,C++,Namespaces,我不知道在嵌套名称空间和对象声明时该怎么做 我正在移植一些代码,这些代码链接到一个只有几个名称空间的静态库 我所说的例子如下: namespace ABC { namespace XYZ { //STUFF } } 在代码中,如何声明命名空间中的对象XYZ 如果我尝试: XYZ::ClassA myobject; 或: 或: 我明白了 不命名类型 错误,即使ClassA肯定存在 这里什么是合适的?这取决于您已经使用的名称空间: 如果您不在任何名称空间或另一

我不知道在嵌套名称空间和对象声明时该怎么做

我正在移植一些代码,这些代码链接到一个只有几个名称空间的静态库

我所说的例子如下:

namespace ABC {

    namespace XYZ {

        //STUFF
    }
}
在代码中,如何声明命名空间中的对象
XYZ

如果我尝试:

XYZ::ClassA myobject;
或:

或:

我明白了

不命名类型

错误,即使
ClassA
肯定存在


这里什么是合适的?

这取决于您已经使用的名称空间:

如果您不在任何名称空间或另一个不相关的名称空间中,则必须指定到整个路径
ABC::XYZ::ClassA

如果您在
ABC
中,您可以跳过
ABC
,只需编写
XYZ::ClassA

另外,值得一提的是,如果要引用不在命名空间(或“根”命名空间)中的函数,可以使用前缀

例如:

int foo() { return 1; }

namespace ABC
{
  double foo() { return 2.0; }

  void bar()
  {
    foo(); //calls the double version
    ::foo(); //calls the int version
  }
}

如果
myobject
是在该命名空间中声明的,并且您想再次声明它(用于定义它),那么您可以通过在其名称前面加前缀来实现,而不是在其类型前面加前缀

ClassA ABC::XYZ::myobject;
如果其类型也在该命名空间中声明,则还需要在类型名称前加前缀

ABC::XYZ::ClassA ABC::XYZ::myobject;

很少需要重新声明这样的对象。通常,对象的第一个声明也是其定义。如果要首先声明对象,必须在该名称空间中进行。下面声明并定义“myobject”

如果您已经在对象中定义了这样的内容,那么可以通过说
ABC::XYZ
来引用它。为了在本地使用该对象,您不必以某种方式“声明”该对象

void f() {
  ABC::XYZ::myobject = someValue;

  // you *can* however use a using-declaration
  using ABC::XYZ::myobject;
  myobject = someValue;
}

正确的方法是ABC::XYZ::ClassA。如果这不起作用,问题在于其他方面。我想说的是——不要使用嵌套的命名空间,让你的命名空间方案尽可能简单。你所尝试的显然是正确的。也许您在实际代码中输入了错误的名称空间/类?你也可以检查字符大小写(这是一个常见的错误)。。。您知道在嵌套的名称空间中声明一个新类不同于从外部库中引用在外部库中声明的对象。@Neil+1。出于组织目的使用嵌套名称空间可能会导致更多的麻烦(ADL与语法负担相关)。我建议严格遵守,以避免名字冲突,并尽可能少地遵守。除非您是在一个非常大的团队中工作,否则一个名称空间应该足以用于一个项目。“通常对象的第一个声明也是它的定义”这似乎是错误的。如果要在头文件中声明某个对象,则不应在其中定义该对象。否则,如果有2个cpp文件包含此标头,并且我们将编译并尝试链接这些cpp文件,则链接器将返回一个关于重复定义的错误。如果第二个代码段即将出现在头中,那么它应该是
名称空间ABC{namespace XYZ{extern ClassA myobject;}}
,然后在相应的cpp文件中应该有
ClassA ABC::XYZ::myobject(如果ClassA不在命名空间中)@Number47为什么它错了?我没有说“所有对象的声明都是定义”,你似乎认为我有定义。@Johnnes我没有说“在所有情况下都是错误的”。但说真的。如果我们谈论的是
名称空间ABC{…}
,那么很可能是关于头文件(我错了吗?)。但是把
ClassA这样的东西放在myobject上是一种不好的做法extern ClassA myobject
或者应该注意的是,此代码段将用于cpp文件中,而不是用于标题中。换句话说,我们可能会误导读者@我不知道你是否错了(我还没有对现有的编码准则进行调查),但我非常认为你错了。我的cpp文件也使用名称空间,而不是在定义名称空间的实体时每次都对名称重复显式限定,如果许多其他程序员都这样做,我也不会感到惊讶。无论如何,多重定义的问题与这个问题完全正交。我还可以为我的最后一个代码片段做一个注释,并说“这个函数不应该放在头中,或者应该是一个成员函数,因为它没有显式地内联声明”。在我看来是噪音。
ABC::XYZ::ClassA ABC::XYZ::myobject;
namespace ABC {
  namespace XYZ {
    ClassA myobject;
  }
}
void f() {
  ABC::XYZ::myobject = someValue;

  // you *can* however use a using-declaration
  using ABC::XYZ::myobject;
  myobject = someValue;
}