Да, это вполне возможно (хотя и весьма сомнительно).#include
на самом деле не более чем текстовое копирование-вставка.Это как если бы ваш Popular.h
был:
namespace Popular {
namespace V3 {
class C {
public:
void print();
};
}
}
Это может быть допустимым кодом C ++, конечно, есть много случаев, когда его не будет.
Обратите внимание, что этот классC
- это ::Popular::V3::C
.Это другой, не связанный тип, тип которого объявлен в V3.h
- ::V3::C
.Второй тип имеет определение своей функции print()
в V3.cpp
.
Но это не тот print()
, который вы вызываете - вы вызываете ::Popular::V3::C::print()
(который, опять же, функция-член другого типа, чем ::V3::C
), и нет определения для этой функциив любом месте.Таким образом, в результате вы получаете неопределенную ссылку - вам нужно добавить определение для этой вещи.Как, скажем,
// Popular.cpp
#include <iostream>
void Popular::V3::C::print() {
std::cout << "This is bad and I should feel bad about it. :-(" << std::endl;
}
Но на самом деле, не #include
вещи внутри namespace
, если у вас нет действительно веской причины для этого.Вместо этого вы могли бы предоставить псевдоним пространства имен:
#include "V3.h"
namespace Popular {
namespace V3 = ::V3;
}
Это позволило бы вам по-прежнему писать Popular::V3::C
, который теперь фактически соответствует типу ::V3::C
.
Или псевдоним типа:
#include "V3.h"
namespace Popular {
using C = ::V3::C;
}
И здесь ::Popular::C
на самом деле тот же тип, что и ::V3::C
.