Рассмотрим эту программу:
line#
1 #include <string>
2
3 using namespace std;
4
5 struct string { const char* p; }; // Beware: another string!
6
7 int main()
8 {
9 string x; // Error: ambiguous - which string is wanted?
10 }
Если вы попытаетесь скомпилировать ее, вы увидите ошибки:
g++ using.cc -o using
using.cc: In function `int main()':
using.cc:9: error: use of `string' is ambiguous
using.cc:5: error: first declared as `struct string' here
/usr/lib/gcc/i386-redhat-linux/3.4.6/../../../../include/c++/3.4.6/bits/stringfwd.h:60: error:
also declared as `typedef struct std::basic_string<char, std::char_traits<char>, std::allocator<char> > std::string' here
using.cc:9: error: `string' was not declared in this scope
using.cc:9: error: expected `;' before "x"
Проблема здесь в том, что когда main()
указывает string x;
компилятор не уверен, нужен ли пользовательский ::string
или включенный std::string
.
Теперь представьте, что вы берете верхнюю часть программы ... строки с 1 по 5 - до и включительноstruct string
... и поместите его в заголовочный файл, который вы затем #include
перед main()
.Ничего не меняется: у вас все еще есть ошибка.Таким образом, так же, как и для автономных программ, заголовочные файлы с операторами using
могут создавать проблемы для другого кода, который включает их, что делает некоторые их операторы неоднозначными.
Хотя это может быть более серьезной болью, так как заголовкиможет быть включен - прямо или косвенно - произвольно огромным количеством зависимого кода и ...
- удаление оператора
using
из заголовка или - изменения всодержимое
<string>
или любого другого заголовка, влияющего на std::
..., может нарушить код, включая проблемный заголовок.Любая проблема может сделать зависимый код некомпилируемым, и проблемы могут даже не быть замечены, пока не будет предпринята другая компиляция.Кроме того, лицо, страдающее из-за оператора using
, может не иметь разрешений для файловой системы / хранилища кодов, корпоративных полномочий и т. Д. Для удаления оператора using
из заголовка или исправления другого уязвимого кода клиента.
Тем не менее, если заголовок имеет «использование» только внутри класса или функции, то это не влияет на код за пределами этой области, поэтому потенциальное влияние изменений в std :: значительно уменьшается.