Безымянное пространство имен против глобальной декларации

Какая разница в использовании безымянного пространства имен и глобального объявления?
Есть ли конкретный контекст для использования этих двух?
Можем ли мы получить доступ к безымянным компонентам пространства имен во внешних исходных файлах?

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).

Другие вопросы по тегам