4

让我们和斗牛犬一起去散步吧:)

假设我有一个命名空间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 到命名空间中,Street就像声明一样。Street::Bulldogusing

然后,我有Owner.hppBulldog前向声明

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

这种现象的自然解释似乎是 C++ 将这两个Bulldog类视为不同的,但为什么呢?在这种情况下,我看不出有任何歧义,即如果编译器正确实施,它实际上可以工作。

你能建议什么解决方法?我能想到的一种方法是简单地删除from和 move from to的前向声明。但是,这将导致精确包含而不是前向声明BulldogOwner.hpp#include "Bulldog.hpp"Owner.cppOwner.hpp

4

2 回答 2

3

看来您可以通过更改Bulldog.hpp说来解决此问题

namespace Street {
    namespace House {
        class Bulldog;
    }
    using House::Bulldog;

    // ...
}

这在 Clang 中对我有用。

于 2013-03-13T00:52:48.293 回答
1

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

由于您要转发声明的类是Street::House::Bulldog,因此您需要House在文件的声明中包含第二个命名空间.hpp

于 2014-09-23T18:43:08.503 回答