it-swarm.com.ru

Превосходство безымянного пространства имен над статическим?

Чем безымянные пространства имен превосходят ключевое слово static?

110
Nawaz

Вы в основном ссылаетесь на раздел $ 7.3.1.1/2 из стандарта C++,

Использование статического ключевого слова не рекомендуется при объявлении объектов в области пространства имен; пространство без имени-имени обеспечивает превосходную альтернативу.

Пространство имен без имени превосходит статическое ключевое слово, прежде всего потому, что ключевое слово static применяется только к объявлениям и функциям переменные, а не к определенным пользователем типам.

Следующий код действителен в C++

   //legal code
   static int sample_function() { /* function body */ }
   static int sample_variable;

Но этот код НЕ действителен:

   //illegal code
   static class sample_class { /* class body */ };
   static struct sample_struct { /* struct body */ };

Таким образом, решение, безымянное пространство имен, что это,

   //legal code
   namespace 
   {  
        class sample_class { /* class body */ };
        struct sample_struct { /* struct body */ };
   }

Надеюсь, это объясняет, почему unnamed-namespace превосходит static.

Кроме того, обратите внимание, что использование статического ключевого слова не рекомендуется при объявлении объектов в области пространства имен (в соответствии со стандартом).

115
Nawaz

Есть интересная проблема, связанная с этим:

Предположим, вы используете ключевое слово staticили безымянное имя namespacename__, чтобы сделать некоторую функцию внутренней для модуля (модуля перевода), поскольку эта функция предназначена для внутреннего использования модулем и недоступна за ее пределами. (Безымянный namespacename__s имеет преимущество в том, что делает данные и определения типов внутренними, помимо функций).

Со временем исходный файл реализации вашего модуля становится больше, и вы хотели бы разделить его на несколько отдельных исходных файлов, что позволило бы лучше организовать код, быстрее находить определения и компилироваться независимо.

Но теперь вы столкнулись с проблемой: эти функции больше не могут быть staticдля модуля, потому что staticна самом деле ссылается не на модуль, а на исходный файл (перевод единица измерения). Вы вынуждены сделать их не -staticname__, чтобы разрешить доступ к ним из других частей (объектных файлов) этого модуля. Но это также означает, что они больше не являются скрытыми/закрытыми для модуля: имея внешнюю связь, они могут быть доступны из других модулей, что было не вашим первоначальным намерением.

Безымянный namespaceтакже не решит эту проблему, поскольку он также определен для определенного исходного файла (единицы перевода) и недоступен извне.

Было бы замечательно, если бы можно было указать, что некоторое namespaceявляется privatename__, то есть все, что в нем определено, предназначено для внутреннего использования модулем, к которому он принадлежит. Но, конечно, C++ не имеет такого понятия, как "модули", только "единицы перевода", которые тесно связаны с исходными файлами.

6
SasQ

Стандарт C++ гласит в разделе 7.3.1.1 Безымянные пространства имен, параграф 2:

Использование статического ключевого слова не рекомендуется при объявлении объектов в области пространства имен. Пространство без имен обеспечивает превосходную альтернативу.

Статика применяется только к именам объектов, функций и анонимных объединений, но не к объявлениям типов.

6
Salgar