Импортирует ли объявление об использовании только перегрузки, объявленные выше объявления об использовании?
Например, 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 ]