我正在开发一个使用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 ++编译?
答案 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_8
。 XERCES_CPP_NAMESPACE
似乎是一个扩展为obixercesc_2_8
的宏。