По мнению комитета по стандартам, почему анонимные пространства имен не являются достаточной заменой статических пространств имен? - PullRequest
47 голосов
/ 11 декабря 2011

Согласно этому ответу , статические переменные в пространстве имен не были определены в C ++ 11.То есть они были объявлены устаревшими в C ++ 03, потому что анонимные пространства имен считались лучшими.Но в C ++ 11 они устарели.

Почему? N3296 перечисляет причины этого следующим образом:

Использование static в области имен не должно рассматриваться как устаревшее.Анонимные пространства имен не являются достаточной заменой функциональности.

Это, по-видимому, было принято комитетом.Зачем?Что это за анонимные пространства имен, которые не полностью заменяют эту функциональность?

Я бы предпочел ответы, которые содержали некоторую документацию или бумажный след обсуждения комитета по стандартам.

Ответы [ 3 ]

34 голосов
/ 11 декабря 2011

Это более подробное объяснение.

Хотя 7.3.1.1 [namespace.unnamed] утверждает, что использование статического ключевого слова для объявления переменных в области пространства имен не рекомендуется, поскольку пространство имен без имени предоставляет превосходную альтернативу, маловероятно, что функция будет удалена в любой точке обозримое будущее, особенно в свете проблем совместимости с C. Комитет должен рассмотреть вопрос об исключении амортизации.

Одна проблема, которую я знаю, заключается в том, что анонимные пространства имен не могут специализировать шаблоны вне блока пространства имен. Вот почему был введен inline namespace, хотя static тоже работает. Кроме того, static очень хорошо играет с макросами.

27 голосов
/ 11 декабря 2011

С безымянными пространствами имен вы не можете задать переменную внутреннюю связь в том же пространстве имен, в котором находитесь в данный момент. С static вы можете. Например, следующее использование безымянных пространств имен не дает глобальной переменной внутреннюю связь

namespace { int a; } 
int a; // oops, no error!

Если бы первый a был объявлен как static, попытка объявить второй a в глобальной области видимости была бы ошибкой, поскольку первый a уже существует в глобальной области действия.

Таким образом, чтобы выполнить свою задачу по созданию уникальных идентификаторов, безымянные пространства имен помещают сущности в разные пространства имен (в дополнение к влиянию на их связь). static только влияет на связь, оставляя пространство имен функций и переменных неизменным.

15 голосов
/ 14 июня 2012

Ответ пользователя в траншеях заключается в том, что имена в безымянных пространствах имен (термин стандарта для анонимных пространств имен) имеют external связь, а имена, объявленные static на уровне пространства имен, имеют internal связь.

Внутренняя связь имеет два преимущества, только одно из которых предоставляют безымянные пространства имен:

  1. Они делают имена локальными для единицы перевода. Я могу по-разному определять одну и ту же функцию fun в разных единицах перевода, не нарушая Правило одного определения. Это свойство совместно используется именами в безымянном пространстве имен, украсив их уникальным именем пространства имен.

  2. Они не позволяют имени войти в глобальную таблицу символов. Это строго оптимизация, но важная на практике. Это свойство не используется совместно именами в безымянном пространстве имен.

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

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

Поэтому я обычно делаю следующее: определяю свободные функции как static, но помещаю типы в безымянное пространство имен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...