Безымянное пространство имен против глобальной декларации
Какая разница в использовании безымянного пространства имен и глобального объявления?
Есть ли конкретный контекст для использования этих двух?
Можем ли мы получить доступ к безымянным компонентам пространства имен во внешних исходных файлах?
2 ответа
Смысл безымянного пространства имен заключается в предоставлении уникального пространства имен в единице перевода (= исходный файл) без необходимости явного префикса. Это позволяет вам гарантировать, что ваши глобальные имена не будут конфликтовать с другими, равными глобальными именами в других единицах перевода.
Например:
// file1.cpp
namespace
{
void foo() { /* ... */ }
}
#include "bar.h"
int do_stuff()
{
foo();
bar();
return 5;
}
// file2.cpp
namespace
{
void foo() { /* ... */ }
}
#include "bar.h"
int do_something else()
{
bar();
foo();
return 12;
}
Вы можете связать эти две единицы перевода вместе и точно знать, что эти два имени foo
будет ссылаться на функцию, определенную в соответствующем файле, и вы не нарушите правило одного определения.
Технически, вы можете думать о безымянном пространстве имен как что-то вроде этого:
namespace unique_and_unknowable_name
{
// ...
}
using namespace unique_and_unknowable_name;
Без этого инструмента единственный способ гарантировать отсутствие нарушения ODR - это использовать static
деклараций. Тем не менее, есть небольшая разница в том, что static
влияет на связь, а пространства имен - нет.
Все имена, объявленные внутри безымянного пространства имен, имеют внутреннюю связь (даже имена, определенные с помощью спецификатора extern).