Это продолжение этого вопроса. Рассмотрим следующий пример:
#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
, и вы согласны с этим?Разве это не очень опасно? Я имею в виду, что если эти вещи происходят в отдельных файлах заголовков без ведома программиста, он/она может в конечном итоге использовать идентификатор, который может быть чем-то совершенно отличным от того, что он/она думает, и компилятор ничего не скажет...
using
, а при объявленииconst string s
). - person Holt   schedule 04.10.2016