Когда целесообразно использовать статические (над неназванными пространствами имен) в С++?

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

#ifndef HEADER_H
#define HEADER_H

static int func() {
  ...
}

// versus:

namespace {
  int func() {
    ...
  }
};

#endif // HEADER_H 

А как насчет статических функций-членов?

Привет

Ответ 1

Точная формулировка стандарта:

Использование ключевого слова static устарело при объявлении объектов в области пространства имен.

Функции в файле заголовка должны быть inline, а не static или в неназванном пространстве имен. inline означает, что у вас будет только одна копия функции в вашей программе, в то время как другие методы предоставят вам отдельную копию из каждого файла, который содержит заголовок. Так же, как и раздувание, это может привести к некорректному поведению, если функция содержит функции-статические данные. ( EDIT:, если функция не должна иметь разные определения в разных единицах компиляции, возможно, из-за разных макросов препроцессора, которые определены до включения заголовочного файла. В этом случае лучший подход заключается не в его включении на самом деле, а скорее похоронить его в немаркированной могиле с колом через ее нечестивое сердце.)

Объекты данных, помимо констант, обычно не должны быть определены в файлах заголовков вообще, только объявлены extern.

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

ОБНОВЛЕНИЕ: С++ 11 удалил устаревание, поэтому больше нет особых причин, чтобы предпочесть неназванные пространства имен над static. Но вы все равно не должны использовать ни в заголовочном файле, если вы не делаете что-то странное.

Ответ 2

В области пространства имен нет преимуществ для статических объектов в пространствах имен, которые я знаю. Используйте неназванные пространства имен, как в приведенном выше примере. На самом деле в приведенном выше примере я не вижу, почему требуется статическое или неназванное пространство имен. Может быть, встроенный? Статические функции-члены не имеют ничего общего со статикой в ​​пространстве пространства имен. Статические функции-члены (и не функциональные элементы) по-прежнему действительны.

Ответ 3

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

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

static для функции-члена не имеет ничего общего с спецификацией привязки. A static функция-член имеет внешнюю привязку в любом случае.

Ответ 4

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

Примерный вопрос, который дает некоторый намек на потенциальную боль в отделе отладки:

Просмотр глобальных переменных, отнесенных к экземплярам в отладчике Visual Studio?

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

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