include和forward声明都有错误

Error with both include and forward declaration

本文关键字:有错误 声明 forward include      更新时间:2023-10-16

我正在开发一个使用ApacheXerces的大型代码库。我正在用clang++构建代码,但它给出了一个错误。

在一个特定的.h文件a.h(a.cpp的头(中,存在类Attributes的头文件的前向声明和包含,如下所示-

#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.pp的相应行,它引发了错误

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

但是,当我注释掉forward声明并在a.h中只包含Attributes标头时,这编译得非常好。当我使用g++而不是clang++时,代码也在构建中。

我不明白一些事情-

1( 当既有正向声明又有include时,为什么它不使用clang++构建

2( 为什么错误指向obixercesc_2_8::Attributes,而不是类Attributes的实际命名空间XERCES_CPP_NAMESPACE::Attributes

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中。CCD_ 11似乎是一个扩展到CCD_ 12的宏。