包含和前向声明都出错

Error with both include and forward declaration

我正在开发一个使用 Apache Xerces 的庞大代码库。我正在使用 clang++ 构建代码,但出现错误。

在特定的 .h 文件 a.h 中,header 对于 a.cpp,存在 class 的 header 文件的前向声明和包含属性如下 -

#include <xercesc/sax2/Attributes.hpp>

namespace XERCES_CPP_NAMESPACE{
    class Attributes;
}

文件 xercesc/sax2/Attributes.hpp 的代码为

XERCES_CPP_NAMESPACE_BEGIN
...<some code>...
class SAX2_EXPORT Attributes {
    ...<some code>... 
}
...<some code>...
XERCES_CPP_NAMESPACE_END

使用 clang 构建代码时出现的错误是

a.cpp:45:39: error: member access into incomplete type 'const obixercesc_2_8::Attributes'
a.h:20:10: forward declaration of 'obixercesc_2_8::obixercesc_2_8::Attributes'
    class Attributes;

这是 a.cpp 中引发错误的对应行

void f(const XERCES_CPP_NAMESPACE::Attributes& attrs) {
 /* this line ---> */ const XMLCh * pAppName = attrs.getValue(X("appName"));

但是,当我注释掉前向声明并仅在 a.h 中包含属性 header 时,编译效果非常好。当我使用 g++ 而不是 clang++ 时,代码也在构建。

有几件事我不明白 -

1)为什么既有前向声明又有include的情况下不使用clang++构建?

2) 为什么错误指向 obixercesc_2_8::Attributes,而不是 XERCES_CPP_NAMESPACE::Attributes,class 属性的实际命名空间?

3) 为什么用g++编译代码?

与其说这是一个解决方案,不如说是一个假设,但无论如何,这是一个想法。

出于某种原因,您在嵌套命名空间 obixercesc_2_8::obixercesc_2_8 中错误地前向声明 Attributes,并且当您引用 obixercesc_2_8::Attributes 时,CLang 选择您的前向声明而不是 Xerces 的实现因为它们不在同一个命名空间中(可能是因为 using namespace 语句?)。从它的角度来看,您有两个 Attributes 声明,一个在 obixercesc_2_8 中,一个在 obixercesc_2_8::obixercesc_2_8 中。 XERCES_CPP_NAMESPACE 似乎是一个扩展为 obixercesc_2_8 的宏。