Конфликт между использованием декларации и предварительной декларацией

Пойдем гулять с бульдогом 🙂

Скажи, у меня есть пространство имен 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::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

Естественным объяснением этого явления является то, что C ++ рассматривает эти 2 Bulldog классы как разные, но почему? Я не вижу никакой двусмысленности в этом случае, то есть он может действительно работать, если правильно реализован компиляторами.

Какие обходные пути вы можете предложить? Я могу думать только о том, чтобы просто удалить предварительная декларация из Bulldog от Owner.hpp и двигаться #include "Bulldog.hpp" от Owner.cpp в Owner.hpp, Тем не менее, это приведет к точному включению, а не предварительная декларация.

3

Решение

Кажется, вы можете исправить это, изменив Bulldog.hpp сказать

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

// ...
}

Это работает для меня в Clang.

3

Другие решения

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 файл.

0

По вопросам рекламы [email protected]