Переобъявление в пространстве имен, которое не включает в себя первоначальное объявление

Член пространства имен может быть определен в пространстве имен, которое охватывает пространство имен объявления:

Члены именованного пространства имен также могут быть определены вне этого пространства имен по явной квалификации (3.4.3.2)
определяемого имени, при условии, что определяемый объект уже был объявлен в пространстве имен
и определение появляется после точки объявления в пространстве имен, которое охватывает декларацию
Пространство имен
.

void f();

namespace N { void ::f() {} }       // illegal for definition

namespace N { void ::f(); }         // what about redeclaration?

Класс может быть определен в пространстве имен, которое содержит пространство имен объявления:

Если class-head-name содержит спецификатор вложенного имени, спецификатор класса должен ссылаться на класс, который был
ранее объявленный
непосредственно в классе или пространстве имен, к которому относится спецификатор вложенного имени, или в
элемент встроенного набора пространств имен (7.3.1) этого пространства имен (т. е. не просто наследуется или вводится
декларация об использовании), и спецификатор класса должен появиться в пространстве имен, включающем предыдущее объявление.
В таких случаях спецификатор вложенного имени класса-заголовка определения не должен начинаться с
decltype-спецификатор.

struct A;

namespace N { struct ::A {}; }      // illegal for definition

namespace N { struct ::A; }         // what about redeclaration?

Также у нас есть одно и то же правило для определения функций-членов и статических данных-членов.

Поэтому мой вопрос заключается в том, является ли переопределение (не определение) законным в пространстве имен, которое не включает в себя первоначальное объявление?

5

Решение

Что касается struct ::A;, [Dcl.type.elab] / 1 делает ваше заявление некорректным:

Если уточненный тип Спецификатор является единственной составляющей
декларация, декларация не оформлена, если это явный
специализация (14.7.3), явная реализация (14.7.2) или Это
имеет одну из следующих форм
:

  ключ-атрибут-спецификатор-ключ-классавыбирать
 идентификатор
;

  friend класс-ключ
::выбирать идентификатор ;
  friend
класс-ключ ::выбирать простой шаблон-идентификатор ;
  friend идентификатор вложенного имени класса
;
  friend спецификатор вложенного имени класса
templateвыбирать простой шаблон-идентификатор ;

Я не вижу проблемы в случае функции; [Dcl.meaning] / 1 разрешает ли это:

Когда
описатель-идентификатор квалифицировано, объявление должно ссылаться на ранее объявленного члена класса или пространства имен
к которому относится квалификатор (или, в случае пространства имен, элемента встроенного набора пространств имен этого пространства имен (7.3.1)) или к его специализации; […] [ Заметка: Если классификатор является глобальным :: оператор разрешения области действия, описатель-идентификатор относится к объявленному имени
в глобальной области имен. — конечная нота ]

Тем не менее, как GCC, так и Clang настаивают на том, что переопределения как определения должны происходить во вложенном пространстве имен.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]