Почему анонимные пространства имен не являются достаточной заменой пространства имен статическими, согласно комитету по стандартам?

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

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

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

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

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

Ответ 1

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

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

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

Ответ 2

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

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

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

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

Ответ 3

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

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

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

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

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

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

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