Однако, по мнению комитета по стандартам , безымянные пространства имен не являются достаточной заменой статическому пространству имен . Еще есть несколько случаев, когда безымянные пространства имен не staticработают и работают.
legends2k
Ответы:
134
Вы в основном имеете в виду раздел §7.3.1.1 / 2 стандарта C ++ 03,
Использование ключевого слова static не рекомендуется при объявлении объектов в области пространства имен; безымянное пространство имен обеспечивает превосходную альтернативу.
Обратите внимание, что этот абзац уже был удален в C ++ 11. стандартные функции больше не staticсчитаются устаревшими!
Тем не менее, пространства имен без названия превосходят ключевое слово static, прежде всего потому, что это ключевое слово staticприменяется только к объявлениям переменных и функциям, а не к определяемым пользователем типам .
Следующий код действителен в C ++
//legal codestaticint sample_function(){/* function body */}staticint sample_variable;
Но этот код НЕ действителен:
//illegal codestaticclass sample_class {/* class body */};staticstruct sample_struct {/* struct body */};
Итак, решение - безымянное пространство имен, то есть
//legal codenamespace{class sample_class {/* class body */};struct sample_struct {/* struct body */};}
Надеюсь, это объясняет, почему unnamed-namespaceлучше static.
Также обратите внимание, что использование ключевого слова static устарело при объявлении объектов в области пространства имен (согласно Стандарту).
В более общем смысле безымянное пространство имен допускает внешнюю связь. Это то, что позволяет объявить класс локальной единицы перевода. Это также позволяет, например, использовать строковую константу внешней связи в качестве аргумента шаблона.
Приветствия и hth. - Альф
10
Как отметил Фред Нурк в другом вашем ответе, похоже, что это deprecatedзамечание было удалено из последней версии C ++ 0x FCD (n3225).
Matthieu M.
36
Вы отвечаете на свой вопрос и благодарите себя: -o
manpreet singh
12
В чем будет разница от простого определения класса в cpp (без анонимного пространства имен, без статики)?
Лучиан Григоре
6
@LuchianGrigore Проблемы со связью в случае 2 .cppсвязаны с определением класса с тем же именем.
Xaqq 03
8
С этим связана интересная проблема:
Предположим, вы используете static ключевое слово или безымянный, namespaceчтобы сделать некоторую функцию внутренней по отношению к модулю (единицей перевода), поскольку эта функция предназначена для внутреннего использования модулем и недоступна вне его. (Безымянный namespaces имеет то преимущество, что делает данные и определения типов также внутренними, помимо функций).
Со временем исходный файл реализации вашего модуля становится большим, и вы хотели бы разделить его на несколько отдельных исходных файлов, что позволило бы лучше организовать код, быстрее находить определения и компилировать независимо.
Но теперь вы сталкиваетесь с проблемой: эти функции больше не могут относиться staticк модулю, потому staticчто на самом деле они относятся не к модулю , а к исходному файлу (единице перевода). Вы вынуждены сделать их запрещенными, staticчтобы разрешить к ним доступ из других частей (объектных файлов) этого модуля. Но это также означает, что они больше не скрыты / закрыты для модуля: имея внешнюю связь, к ним можно получить доступ из других модулей, что не было вашим первоначальным намерением.
Без имени namespaceтакже не решит эту проблему, потому что он также определен для определенного исходного файла (единицы перевода) и не может быть доступен извне.
Было бы замечательно, если бы можно было указать, что some namespaceis private, то есть все, что в нем определено, предназначено для внутреннего использования модулем, которому он принадлежит. Но, конечно, в C ++ нет понятия «модули», только «единицы перевода», которые жестко привязаны к исходным файлам.
В любом случае это будет взлом и ограниченное решение, но вы можете включить файл (ы) cpp с внутренними статическими функциями или функциями с именами в свои «основные» файлы cpp. Затем исключите эти «вспомогательные» файлы cpp из сборки, и все готово. Единственная проблема, если у вас есть два или более «основных» файла cpp, и они оба хотят использовать эту классную функцию из одного из «вспомогательных» файлов cpp ...
Сергей
не использует ли наследование с частным / защищенным / общедоступным со статическими функциями решения?
Али
C ++ 20 вводит модули, которые решают вашу проблему.
static
работают и работают.Ответы:
Вы в основном имеете в виду раздел §7.3.1.1 / 2 стандарта C ++ 03,
Обратите внимание, что этот абзац уже был удален в C ++ 11. стандартные функции больше не
static
считаются устаревшими!Тем не менее, пространства имен без названия превосходят ключевое слово static, прежде всего потому, что это ключевое слово
static
применяется только к объявлениям переменных и функциям, а не к определяемым пользователем типам .Следующий код действителен в C ++
Но этот код НЕ действителен:
Итак, решение - безымянное пространство имен, то есть
Надеюсь, это объясняет, почему
unnamed-namespace
лучшеstatic
.Также обратите внимание, что использование ключевого слова static устарело при объявлении объектов в области пространства имен (согласно Стандарту).источник
deprecated
замечание было удалено из последней версии C ++ 0x FCD (n3225)..cpp
связаны с определением класса с тем же именем.С этим связана интересная проблема:
Предположим, вы используете
static
ключевое слово или безымянный,namespace
чтобы сделать некоторую функцию внутренней по отношению к модулю (единицей перевода), поскольку эта функция предназначена для внутреннего использования модулем и недоступна вне его. (Безымянныйnamespace
s имеет то преимущество, что делает данные и определения типов также внутренними, помимо функций).Со временем исходный файл реализации вашего модуля становится большим, и вы хотели бы разделить его на несколько отдельных исходных файлов, что позволило бы лучше организовать код, быстрее находить определения и компилировать независимо.
Но теперь вы сталкиваетесь с проблемой: эти функции больше не могут относиться
static
к модулю, потомуstatic
что на самом деле они относятся не к модулю , а к исходному файлу (единице перевода). Вы вынуждены сделать их запрещенными,static
чтобы разрешить к ним доступ из других частей (объектных файлов) этого модуля. Но это также означает, что они больше не скрыты / закрыты для модуля: имея внешнюю связь, к ним можно получить доступ из других модулей, что не было вашим первоначальным намерением.Без имени
namespace
также не решит эту проблему, потому что он также определен для определенного исходного файла (единицы перевода) и не может быть доступен извне.Было бы замечательно, если бы можно было указать, что some
namespace
isprivate
, то есть все, что в нем определено, предназначено для внутреннего использования модулем, которому он принадлежит. Но, конечно, в C ++ нет понятия «модули», только «единицы перевода», которые жестко привязаны к исходным файлам.источник