Подтвердить что ты не робот

Как правильно ссылаться на функцию в анонимном пространстве имен

Рассмотрим этот фрагмент кода С++:

namespace
{
    void f()
    {
    }

    class A
    {
        void f()
        {
            ::f(); // VC++: error C2039: 'f' : is not a member of '`global namespace''
        }
    };
}

GCC компилирует это просто отлично. Visual С++ 2008 не удается скомпилировать ошибку C2039. Какой из этих двух компиляторов прав здесь? Есть ли способ правильно ссылаться на этот "глобальный" f?

Изменить: Зак предложил попробовать, и он работает с обоими компиляторами. Мне немного странно.

namespace
{
    void f()
    {
    }

    class A
    {
        void f();
    };
}

void A::f()
{
    ::f();
}
4b9b3361

Ответ 1

VС++ 2008 здесь не так. Согласно стандарту С++ 03 3.4.3.4:

Имя, предваряемое унарной областью оператор:: (5.1) просматривается в глобальный охват, в блоке перевода где он используется. Имя должно быть объявляется в глобальной области пространства имен или это имя, чья декларация видимый в глобальном масштабе из-за с использованием директивы (3.4.3.2). Использование:: позволяет глобальное имя упоминается, даже если его идентификатор имеет были скрыты (3.3.7).

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

И согласно 7.3.1.1/1 анонимное пространство имен эквивалентно:

namespace *unique* { /* empty body */ }
using namespace *unique*;
namespace *unique* { namespace-body }

Таким образом, между этими двумя разделами автономная функция должна быть доступна в глобальном пространстве имен.

Ответ 2

Как отметил академик Robot, Visual С++ ошибочен. В качестве обходного пути добавление пустого безымянного блока пространства имен должно устранить проблему (у меня нет Visual С++ 2008 для тестирования, но это работает в Visual С++ 2010):

// empty unnamed namespace to placate compiler
namespace { }

namespace {
    void f() { }
    struct A {
        void f() { ::f(); }
    };
}

Я сообщил об этой проблеме команде Visual С++.