Импортирует ли объявление об использовании только перегрузки, объявленные выше объявления об использовании?

Например, GCC и clang не могут скомпилировать следующий код:

struct S {};

namespace N
{
    void g(S);
}

using N::g;

namespace N
{
    void g(int);
}

int main()
{
    g(0);
}

с ошибкой:

test.cpp: In function 'int main()':
test.cpp:17:8: error: could not convert '0' from 'int' to 'S'
     g(0);
        ^

Предполагается, что объявление-использование импортирует только перегрузки, объявленные выше точки, где появляется объявление-использование, а не те, которые могут появиться позже (но до использования имени).

Это поведение правильно?

1 ответ

Решение

Это поведение правильно?

Да, это поведение правильно и хорошо определено в соответствии со стандартом C++.

Соответствующим разделом является п. 7.3.3.11 стандарта C++11:

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

[ Example:    
    namespace A {
        void f(int);
     }
    using A::f; // f is a synonym for A::f;
    // that is, for A::f(int).
    namespace A {
        void f(char);
    }
    void foo() {
        f(’a’); // calls f(int),
    } // even though f(char) exists.
    void bar() {
        using A::f; // f is a synonym for A::f;
        // that is, for A::f(int) and A::f(char).
        f(’a’); // calls f(char)
    }
 —end example ]
Другие вопросы по тегам