Следующее определение пространства имен не может быть скомпилировано, когда первое объявление закомментировано. Если первая декларация foo
не комментируется, то компилируется просто отлично.
namespace Y
{
//void foo();
void ::Y::foo(){}
}
Соответствующая часть в стандарте (§8.3¶1) гласит:
Когда идентификатор объявления определен, объявление должно ссылаться на ранее объявленного члена
Я понимаю, что это правило предотвращает введение имен в другие пространства имен. Интересно, можно ли смягчить это правило, чтобы учесть Квалифицированный-идентификаторs ссылается на текущее пространство имен.
CWG # 482 актуально:
В соответствии с 8.3 [dcl.meaning] параграф 1, […]
Это ограничение запрещает примеры, подобные следующим:void f(); void ::f(); // error: qualified declarator namespace N { void f(); void N::f() { } // error: qualified declarator }
Кажется, нет веских причин для запрета таких
декларации и ряд реализаций принимают их, несмотря на
запрет стандарта. Если стандарт будет изменен, чтобы позволить
их?Примечания от апрельской встречи 2006 года:
В обсуждении выпуск 548, CWG решила, что запрет
квалифицированные деклараторы внутри их пространства имен должны быть удалены.
Таким образом, ваш код действителен, если первое объявление foo
присутствует (по состоянию на 2012 год; GCC имеет открыть отчет об ошибке). Если нет, однако, ваша цитируемая формулировка все еще применяется и делает квалифицированную декларацию неверной. Я не вижу причин разрешать это дело; оно интуитивно подразумевает, что имя уже объявлено, поскольку поиск по квалифицированному имени должен определить, к чему оно относится.
Других решений пока нет …