#c #namespaces #language-lawyer
#c #пространства имен #язык-юрист
Вопрос:
Существует цитата из раздела 3.4.3.2 / 3:
Учитывая X::m (где X — объявленное пользователем пространство имен) или given ::m (где X — глобальное пространство имен), если S(X, m) — пустое множество, программа неправильно сформирована. В противном случае, если S(X, m) имеет ровно один элемент, или если контекст ссылки представляет собой using-declaration (7.3.3), S(X, m) является требуемым набором объявлений m .
Определение S(X,m) приведено в следующем разделе. 3.4.3.2 / 2:
Для пространства имен X и имени m набор поиска S(X, m), определяемый пространством имен, определяется следующим образом: пусть S (X, m) — это набор всех объявлений m в X и встроенное пространство имен X (7.3.1). Если S (X, m) не является пустым, S(X, m) равно S (X, m); в противном случае S(X, m) является объединением S(Ni , m) для всех пространств имен Ni, назначенных с помощью-directives в X и его встроенном наборе пространств имен.
Теперь рассмотрим следующий код:
#include <iostream>
using namespace std;
namespace N
{
int cout = 6;
}
using namespace N;
int main() {
using ::cout;//error: reference to ‘cout’ is ambiguous
return 0;
}
Я не понимаю эту ошибку. Приведенный выше код не противоречит правилу:
если S(X, m) имеет ровно один элемент, или если контекст ссылки представляет собой using-declaration (7.3.3), S(X, m) — это требуемый набор объявлений m.
Можете ли вы объяснить смысл этого правила?
Комментарии:
1. Вы забыли упомянуть, что
cout
вы ожидали от этогоusing
предложения для идентификации.2. Для функций набор всех объявлений с несколькими значениями (может) не иметь конфликта и двусмысленности, для классов и экземпляра объекта неясно, какой из них вы хотите.
Ответ №1:
Дмитрий, я подозреваю, что вы неверно истолковываете, что означает «если контекст ссылки является using-declaration«. «В контексте using-declaration» не означает «при использовании в using-declaration«. Вместо этого это означает «когда ссылка является предметом using-declaration«. Предположим, что ваш код изменен следующим образом:
int main() {
using N::cout;
std::cout << "value=" << cout << 'n';
}
Обратите внимание на использование неквалифицированного cout
in std::cout << "value=" << cout << 'n'
. Контекстом этой неквалифицированной ссылки является using-declaration using N::cout
.
Другой способ взглянуть на то, что означает стандарт, заключается в том, что using-declaration имеет приоритет над using-directive .