跨不同命名空间的好友 类 无法正常工作且无法识别命名空间
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,但是后来我在另一个文件中出现歧义,我在其中使用 MeshNamespace
和 ReferenceElementNamespace
以及 using
。这仍然没有解决任何问题
我知道的:
- 支持(其他)命名空间中的前向声明。
- 不支持嵌套 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;
};
注:
自 C++17 起,允许嵌套命名空间定义:
namespace X::Y { }
被认为等于 namespace X { namespace Y { } }
.
class 定义似乎也是如此。所以,添加一个定义
class MeshNamespace::Mesh { };
在namespace MeshNamespace
定义一次后就可以了。
(但是,在 namespace MeshNamespace
至少定义一次之前,这也是一个错误。)
我在 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,但是后来我在另一个文件中出现歧义,我在其中使用 MeshNamespace
和 ReferenceElementNamespace
以及 using
。这仍然没有解决任何问题
我知道的:
- 支持(其他)命名空间中的前向声明。
- 不支持嵌套 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;
};
注:
自 C++17 起,允许嵌套命名空间定义:
namespace X::Y { }
被认为等于 namespace X { namespace Y { } }
.
class 定义似乎也是如此。所以,添加一个定义
class MeshNamespace::Mesh { };
在namespace MeshNamespace
定义一次后就可以了。
(但是,在 namespace MeshNamespace
至少定义一次之前,这也是一个错误。)