包含和转发声明均出错

时间:2016-09-22 06:31:05

标签: c++ include forward-declaration clang++ xerces

我正在开发一个使用Apache Xerces的庞大代码库。我正在用clang ++构建代码并且它给出了一个错误。

在特定的.h文件a.h中,a.cpp的标头,有类别属性的头文件的前向声明和包含,如下所示 -

#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中的Attributes头时,这个编译完全正常。当我使用g ++而不是clang ++时,代码也在构建。

我不了解一些事情 -

1)当有前向声明和包含时,为什么不用clang ++构建?

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

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

1 个答案:

答案 0 :(得分:1)

这更像是一种假设,而不是一种解决方案,但无论如何,这是一种思想。

出于某种原因,你在嵌套的命名空间Attributes中错误地向前声明obixercesc_2_8::obixercesc_2_8,当你提到obixercesc_2_8::Attributes时,CLang会选择你对Xerces实现的前向声明,因为它们是不在同一名称空间中(可能是因为using namespace语句?)。从它的观点来看,你有两个Attributes声明,一个在obixercesc_2_8,一个在obixercesc_2_8::obixercesc_2_8XERCES_CPP_NAMESPACE似乎是一个扩展为obixercesc_2_8的宏。