Отличия анонимного пространства имён от static
Зачем нужен анонимный namespace, если есть ключевое слово static, которое также делает символ локальным для его единицы трансляции?
Ответы (2 шт):
В комментариях уже все сказали:
- Меньше писанины, если статических сущностей нужно много.
- Действует не только на переменные/функции, но и на классы.
Буду благодарен за любое замечание, я расскажу как сам понимаю...
Просто нужно понять, что имена из пространства имен являются собственностью файла.
Допустим у нас есть файл(не важно, что пример несколько вздорный, главное понять суть):
A.h
static char foo() { return '?'; }
void g();
В файле статическая функция уже определена,определение другой функции придется поискать в другом месте. И вот это место:
A.cpp
#include "A.h"
раз я подключил A.h, то имею функцию foo, которая уникальна для этой единицы трансляции, поэтому тут я не могу определять еще одну такую же функцию. Но безымянное пространство имен дает возможность страховаться от повторного определения, и полагаясь на то, что дальше будет доступен только заголовочный файл, могу записать:
/* тут все верно, файл имеет свою собственную foo*/
namespace {
char foo() { return 'c'; }
void f() { std::cout << foo(); }
}
//static char foo() { return 'R'; } это было бы (ошибкой)повторным определением
void g() {
f();
}
- нужно обращать внимание на то, что нельзя напрямую вызвать
fooиз за неоднозначности. Но само пространство имен есть отдельное пространство, где можно обращаться ко всем именам из этого пространства, избегая от повторного определения. - И
fбудет вызывать именноfooиз своего пространства имен.
И если мы где то еще подключим "A.h" и вызовем g то компилятор не найдет определение, и делом возьмется компановщик, который найдет определение вызывающее foo из безымянного пространства имен. При вызове foo, определение уже известно, и будет вызвана функция заголовочного файла.
P.S. Любой инструмент дает дополнительную возможность. Действуйте по ситуации, и лучше просто избегать от повторения имен и от глобальных объектов.