Как неназванные пространства имен превосходят ключевое слово static
?
Превосходство неназванного пространства имен над статикой?
Ответ 1
В основном вы ссылаетесь на раздел $7.3.1.1/2 из С++ Standard,
Использование ключевого слова static устарел при объявлении объектов в область пространства имен; безымянное пространство имен обеспечивает превосходное альтернатива.Забастовкa >
Пространство имен, превосходящее статическое ключевое слово, главным образом потому, что ключевое слово static
применяется только к объявлениям и функциям переменных, а не к пользовательским типам.
Следующий код действителен в С++
//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
.
Также обратите внимание, что использование статического ключевого слова не рекомендуется при объявлении объектов в области пространства имен (в соответствии со стандартом).
Забастовкa >
Ответ 2
Стандарт С++ читается в разделе 7.3.1.1. Пространства имен, абзац 2:
Использование ключевого слова static устарел при объявлении объектов в область пространства имен, пространство имен без имени обеспечивает превосходную альтернативу.
Статичность применяется только к именам объектов, функций и анонимных объединений, а не к типу объявлений.
Ответ 3
Есть интересная проблема, связанная с этим:
Предположим, вы используете ключевое слово static
или unnamed namespace
, чтобы сделать некоторую функцию внутренней для модуля (единицы перевода), так как эта функция предназначена для внутреннего использования модулем и не доступна вне его. (Безымянный namespace
имеет то преимущество, что внутренние и внутренние определения типов тоже, помимо функций).
С течением времени исходный файл реализации вашего модуля растет, и вы хотите разбить его на несколько отдельных исходных файлов, что позволит лучше организовать код, быстро найти определения и скомпилироваться независимо.
Но теперь у вас возникла проблема: эти функции больше не могут быть static
для модуля, потому что static
фактически не ссылается на модуль, а на исходный файл (единица перевода). Вы вынуждены сделать их не static
, чтобы они могли быть доступны из других частей (объектных файлов) этого модуля. Но это также означает, что они больше не скрыты/закрыты для модуля: с внешней связью они могут быть доступны из других модулей, что не было вашим первоначальным намерением.
Без названия namespace
также не будет решена эта проблема, поскольку она также определена для конкретного исходного файла (единицы перевода) и не может быть доступна извне.
Было бы здорово, если бы можно было указать, что некоторые namespace
есть private
, то есть все, что определено в нем, предназначено для внутреннего использования модулем, к которому он принадлежит. Но, конечно, у С++ нет такой концепции, как "модули", только "единицы перевода", которые тесно связаны с исходными файлами.