Превосходство безымянного пространства имен над статическим? - PullRequest
112 голосов
/ 12 декабря 2010

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

Ответы [ 3 ]

115 голосов
/ 12 декабря 2010

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

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

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

Следующий код действителен в 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.

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

6 голосов
/ 27 марта 2014

Существует интересная проблема, связанная с этим:

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

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

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

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

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

6 голосов
/ 12 декабря 2010

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

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

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

...