Ненужное использование безымянных пространств имен Переполнение стека

Я продолжаю видеть такой код везде в моей компании:

namespace {

const MAX_LIMIT = 50;
const std::string TOKEN = "Token";

}

Я не совсем понимаю, зачем вам здесь анонимное пространство имен. С одной стороны, вы хотите локальный переводчик для MAX_LIMIT А ТАКЖЕ TOKEN, Но это уже достигается без анонимного пространства имен из-за const, static const и просто const оба добиваются местного перевода.

С другой стороны, у вас нет столкновений имен, если где-то в вашем файле есть переменная с таким же именем.

int foo()
{
std::string TOKEN = "MyToken"; // Clash! ::TOKEN vs TOKEN can be used.
}

Это оправдало бы анонимное пространство имен. Но как часто вам нужно имя переменной в вашей функции, которая на самом деле уже занято const переменная объявлена ​​вне вашей функции? Мой ответ никогда. Так что на практике для меня безымянное пространство имен не нужно. Есть намеки?

6

Решение

В этом конкретном случае пространство имен действительно избыточно, потому что переменные области видимости пространства имен const действительно имеют внутреннюю связь по умолчанию.

Рассмотрим возможность изменения кода позже. Возможно, одна из переменных не должна быть константой в конце концов. Но неконстантность также изменяет стандартную связь. Анонимное пространство имен сохранит внутреннюю связь даже после такого изменения. Другими словами, пространство имен anon разделяет заботы о константности и связи. Хорошо ли это, зависит от контекста.

Обратите внимание, что то же самое может быть достигнуто с помощью static ключевое слово. Поскольку это имеет тот же эффект, что и пространство имен anon, выбор в основном эстетичен и, следовательно, основан на мнении.

Аргумент для использования пространств имен anon вместо static может быть последовательность. Вы не можете определить типы с внутренней связью с static, Поскольку некоторые внутренние символы (типы) не могут быть определены вне анонимного пространства имен, вы можете иметь соглашение для определения всех внутренних символов в анонимном пространстве имен. Конечно, такая конвенция, как правило, будет делом вкуса.

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

3

Другие решения

namespace избыточно, как вы объясняете. Вы можете удалить namespace { и соответствие } ,

Единственное отличие состоит в том, что вы можете иметь разные имена ::TOKEN а также unnamed_namespace::TOKEN, Но это, вероятно, только добавляет путаницу, и было бы лучше получить ошибку компиляции.

Не уверен, что вторая половина вашего поста, локальная переменная TOKEN тени как ::TOKEN а также unnamed_namespace::TOKEN, Таким образом, изменение не будет иметь никакого значения для этого случая.

5

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

0
По вопросам рекламы [email protected]