Это продолжение до этот вопрос. Рассмотрим следующий пример:
#include <iostream>
namespace MyProject {
class string {
public: string() { std::cout << "Callin string constructor" << std::endl; }
};
}
namespace Other {
class string {};
}
namespace MyProject {
using Other::string;
}
namespace MyProject {
void useString() {
const string s;
}
}
int main() {
MyProject::useString();
}
Здесь компилятор правильно выдает ошибку в строке using Other::string
, жалуясь, что декларация для string
уже существует в этом пространстве имен, исходя из предыдущего class string
определение.
Теперь рассмотрим это:
#include <iostream>
namespace MyProject {
class string {
public: string() { std::cout << "Callin string constructor" << std::endl; }
};
}
namespace Other {
class something {};
using string = something;
}
namespace MyProject {
using Other::string;
}
namespace MyProject {
void useString() {
const string s;
}
}
int main() {
MyProject::useString();
}
Здесь нет ошибки компиляции: мне удалось скрыть предыдущее объявление string
с новым.
Почему нет ошибки во втором случае? Это потому что using string = something
не факт декларация, так как это псевдоним и настоящая декларация для something
имя, и компилятор может только обнаружить конфликты между фактическими объявлениями, поэтому в этом случае он подумает, что я действительно объявляю something
а также string
и быть в порядке с этим?
Разве это не опасно? Я имею в виду, что если эти вещи происходят в отдельных заголовочных файлах, и программист не осознает этого, он / она может использовать идентификатор, который может быть чем-то совершенно отличным от того, что он / она думает, и что компилятор ничего не скажет …
Задача ещё не решена.
Других решений пока нет …