跨不同命名空间的好友 类 无法正常工作且无法识别命名空间

Friend classes across different namespaces not working and namespace is not recognized

我在 C++ 中使用 friend class 时遇到问题 我提前声明朋友 class 并使用适当的命名空间,所以我不知道发生了什么。 在 class MeshNamespace::Mesh 内部, ReferenceElementNamespace::ReferenceElement 的成员仍然无法访问前者的私有成员。此外在 ReferenceElement.hpp 中,无法识别 MeshNamespace 标识符。

如果我在没有命名空间的情况下将其转发声明为 class Mesh;,它不会抱怨,但仍然无法正常工作,就好像根本没有转发声明一样;

//文件ReferenceElement.hpp

namespace ReferenceElementNamespace {
    class MeshNamespace::Mesh; // ReferenceElement.hpp:27:9: error: use of undeclared identifier 'MeshNamespace'
    class ReferenceElement : public IReferenceElement 
  {
  private:
  vector<Polygon> _referenceElementPolygons;   //(**)
  friend class MeshNameSpace::Mesh; //ReferenceElement.hpp:45:20: error: use of undeclared identifier 'MeshNameSpace'
  };
}

//文件Mesh.hpp

#include "Mesh.hpp"
    using namespace ReferenceElementNamespace;
    namespace MeshNamespace {
          class Mesh : public IMesh{
                  someFunction(ReferenceElement& referenceElement)
                  {
                    ReferenceElement ref;
                    Polygon &polygon = ref._referenceElementPolygons[0];  //Mesh.cpp:216:32: error: '_referenceElementPolygons' is a private member of 'ReferenceElementNamespace::ReferenceElement'
    ReferenceElement.hpp:34:23: note: declared private here   // in line (**)
                  }
         };
    }

编辑:顺便说一下,我意识到前向声明 class Mesh; 而不是 class MeshNamespace::Mesh; 会被接受,因为它就像在命名空间 ReferenceElementNamespace 中声明一个新的 class,但是后来我在另一个文件中出现歧义,我在其中使用 MeshNamespaceReferenceElementNamespace 以及 using。这仍然没有解决任何问题

我知道的:

  1. 支持(其他)命名空间中的前向声明。
  2. 不支持嵌套 classes 的前向声明。

OP 写道:

class MeshNamespace::Mesh;

class OtherClass {
friend class MeshNamespace::Mesh;
};

namespace MeshNamespace 中转发声明 class Mesh

也可以是 class MeshNamespace { class Mesh { } },但这是嵌套 class 的前向声明(不支持)。

不知道怎么区分,好像编译器也不行。但是,修复很简单:

namespace MeshNamespace {
class Mesh;
}

class OtherClass {
friend class MeshNamespace::Mesh;
};

Demo on coliru


注:

自 C++17 起,允许嵌套命名空间定义:
namespace X::Y { } 被认为等于 namespace X { namespace Y { } }.

class 定义似乎也是如此。所以,添加一个定义

class MeshNamespace::Mesh { };

namespace MeshNamespace定义一次后就可以了。 (但是,在 namespace MeshNamespace 至少定义一次之前,这也是一个错误。)

Demo on coliru