让我们和Bulldog一起散步:)
假设我有一个名称空间Street::House
(在名称空间Street
内),其中类Bulldog
声明为(让它在House/Bulldog.hpp
中) :
namespace Street {
namespace House {
class Bulldog {};
}
}
然后,我有Bulldog.hpp
:
#include "House/Bulldog.hpp"
namespace Street {
using House::Bulldog;
}
注意正在发生的事情:我Street::House::Bulldog
<{1}}的{{1}}声明为Street
Street::Bulldog
using
声明Owner.hpp
。
然后,我有Bulldog
,其中namespace Street {
class Bulldog;
class Owner {
Bulldog* bulldog;
};
}
类向前宣布:
Owner.cpp
最后,我有#include "Owner.hpp"
#include "Bulldog.hpp"
namespace Street {
// Implementation of Owner...
}
:
Owner.cpp
error: 'Bulldog' is already declared in this scope
:
Bulldog
这种现象的自然解释似乎是C ++将这两个Bulldog
类视为不同,但为什么呢?在这种情况下,我看不出任何歧义,即如果编译器正确实现,它实际上可以工作。
您可以建议哪些变通方法?我能想到的只是从Owner.hpp
移除#include "Bulldog.hpp"
的前向声明,并将Owner.cpp
从Owner.hpp
移到{{1}}。但是,这将导致完全包含而不是前向声明。
答案 0 :(得分:3)
您似乎可以通过将Bulldog.hpp
更改为
namespace Street {
namespace House {
class Bulldog;
}
using House::Bulldog;
// ...
}
这对Clang来说很有用。
答案 1 :(得分:0)
Owner.hpp
:
namespace Street {
class Bulldog;
class Owner {
Bulldog* bulldog;
};
}
应该是
namespace Street {
namespace House {
class Bulldog;
}
class Owner {
House::Bulldog* bulldog;
};
}
您不小心向前宣布Street::Bulldog
,而不是真正的班级,而不是Street::House::Bulldog
,其中 是真正的班级。因此,您在Owner.cpp
中的实施受到了骚扰,因为Bulldog*
含糊不清。它不知道你是引用声明的类Street::Bulldog
还是声明的(也是定义的,虽然编译器不关心)Street::House::Bulldog
。 / p>
由于您要转发声明的类是Street::House::Bulldog
,因此您需要在House
文件的声明中包含第二个.hpp
命名空间。