Это неправильно или правильно сформировано в соответствии со стандартом С++?
namespace M { struct i {}; }
namespace N { static int i = 1; }
using M::i;
using N::i;
int main() { sizeof (i); }
Clang отклоняет его, а GCC принимает.
Согласно [namespace.udir-6] (http://eel.is/c++draft/basic.namespace#namespace.udir-6):
Если поиск имени находит объявление имени в двух разных пространствах имен, и объявления не объявляют одну и ту же сущность и не объявляют функции, использование имени является неверным.
Как мы должны интерпретировать это? Помните, что каждая декларация использования объявляет имя через [namespace.udecl]p1 (http://eel.is/c++draft/namespace.udecl#1):
Объявление-использования вводит имя в декларативную область, в которой появляется объявление-использования.
объявление-использования:
using typename
opt описатель вложенного-имени неполный-id;
Имя члена, указанное в объявлении-использования, объявляется в области деклараций, в которой появляется объявление-использования. [Примечание: объявляется только указанное имя; указание имени перечисления в объявлении использования не объявляет его перечислители в декларативной области объявления использования. — конец примечания ] Если объявление-использования называет конструктор ([class.qual]), оно неявно объявляет набор конструкторов в классе, в котором появляется объявление-использования ([class.inhctor]); в противном случае имя, указанное в декларации использования, является синонимом набора объявлений в другом пространстве имен или классе.
Итак, у нас есть 4 объявления имени i.
Что из этого находит неполный поиск имени i
в sizeof(i)
?
Находит ли он только using M::i;
и using N::i;
, которые находятся в одном и том же пространстве имен (глобальном пространстве имен), поэтому программа имеет правильный формат?
Или он находит только struct i {};
и static int i = 1;
, которые находятся в разных пространствах имен, поэтому программа имеет неправильный формат?
Или у нас есть другая альтернатива?