Анонимные пространства имен: действительно ли они так хороши? - PullRequest
16 голосов
/ 23 декабря 2010

Я давно использовал ключевое слово static для определения внутренней связи.Позже я переключился на стиль C ++, заключающий в себе локальные вещи в анонимных пространствах имен.

Однако теперь, когда я несколько лет работал с анонимными пространствами имен, я начинаю думать, что ключевое слово static намного прощеработать с!

Распространенная проблема заключается в том, что у меня есть такой шаблон:

namespace {
    // ...five pages of code...
}  // namespace

Чтобы увидеть, имеет ли определенная функция внутреннюю или внешнюю связь, мне нужно много прокручивать, в отличиек старому стилю C, где я мог просто проверить, было ли перед функцией / объектом static.

Я знаю, что есть вещи, которые анонимные пространства имен делают, которые static не может - скрыть typedefs - нолично меня это не особо интересует, во всяком случае.

Что вы думаете об этом?Является ли победа анонимных пространств имен настолько большой, что она гарантирует снижение читабельности?Или я не прав?

Ответы [ 3 ]

20 голосов
/ 23 декабря 2010

Если код в вашем пространстве имен слишком длинный, ничто не мешает вам сделать это:

namespace {
    int foo(char* x) {
        return x[0] + x[1];
    }
}

namespace {
    int bar(char *x, char *y) {
        return foo(x) + foo(y);
    }
}

В C ++ 03 практическим преимуществом использования безымянного пространства имен является именно то, что содержимое имеет внешняя связь (но все еще невидимы вне TU, потому что нет никакого способа обратиться к ним).Параметры шаблона не могут иметь внутреннюю связь:

namespace {
    int foo(const char* x) {
        return x[0] + x[1];
    }
}

static int foo2(const char *x) {
    return x[0] + x[1];
}

template <int (*F)(const char*)>
void baz(const char *p) {
    F(p);
}

int main() {
    baz<foo>("ab");   // OK
    baz<foo2>("ab");  // not valid
}
2 голосов
/ 08 декабря 2012

Помимо очень важных моментов, отмеченных Стивом, я вижу и другие очень важные аспекты в анонимных пространствах имен, которые делают их превосходящими статические функции: Локальность, простота рефакторинга и сокрытие информации .

Предположим, у вас есть одна или две функции класса, которые требуют нескольких других вспомогательных функций, которые являются довольно конкретными, но не используют членов класса.Если вы будете придерживаться Роберта С. Мартина (функции должны быть небольшими и служить одной четко определенной цели), вы часто обнаружите, что большие функции могут быть реорганизованы в более мелкие, хотя эти меньшие вначале могли бы использоваться только в прежней большой функции.

Итак, какие у вас есть варианты:

  1. Создайте новый (возможно частный) класс немедленно:

    Это влечет за собой довольномного печатания может быть излишним, и, скажем так, все это иногда ленится или спешит.

  2. Создание частных статических функций или функций, не являющихся членами:

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

  3. Пространство анонимных имен:

    У вас есть вспомогательная функция, которая не требует доступа к элементу и служит одной цели -> Поместите ее туда и напишите этоФункция близка к методам класса, где она будет использоваться.По большому счету это мой любимый вариант: он быстрый и не загромождает заголовочный файл.Пространство имен ясно заявляет: это не используется ничем иным, кроме этого cpp.Ни один друг не будет использовать его, и ни один пользователь библиотеки никогда не узнает о его существовании.Вы вряд ли можете быть более очевидным, и часто эта парадигма приводит к более четкой конструкции функции, которая состоит из нескольких входных параметров и изменен только один выход.Далее у вас есть локальность функции: Определите непосредственно перед основным использованием.Хотя это может быть недостатком, я считаю его весьма полезным при просмотре реализаций больших классов.Другое преимущество - это константы, которые охватывают несколько функций, но не очень интересны для пользователя библиотеки.Поместите их также в пространство имен, лучше всего с теми функциями, которые их используют.Если позже выяснится, что вам нужны константы и функции в другом месте, преобразуйте целое в класс, который уже аккуратно упакован.

Отказ от ответственности: Многие люди могут утверждать, что использование прыща намного чище.Это только мое личное мнение.

1 голос
/ 15 ноября 2012

Анонимное пространство имен - единственное, что не позволяет объявлению класса загрязнять глобальную область видимости. Очень полезно при определении класса в файле .cpp.

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