Я думал, что во вложенном пространстве имен все, что является частью родительского (или глобального) пространства имен, одинаково рассматривается для разрешения перегрузки, но этот пример, похоже, показывает иное.
Это отлично работает:
#include <iostream>
void foo(int) { std::cout << "int\n"; }
void foo(float) { std::cout << "float\n"; }
namespace NS {
void bar() {
foo(0);
}
}
int main() {
NS::bar();
}
Вызов foo(0)
соответствует foo(int)
, так как это лучший вариант, и все работает, как ожидалось. Однако, если я перенесу объявление foo(float)
в пространство имен:
#include <iostream>
void foo(int) { std::cout << "int\n"; }
namespace NS {
void foo(float) { std::cout << "float\n"; }
void bar() {
foo(0);
}
}
int main() {
NS::bar();
}
Теперь вызов foo(0)
вызывает foo(float)
!
Я искал через https://en.cppreference.com/w/cpp/language/overload_resolution и многие другие подобные страницы, чтобы найти правило, объясняющее это, но мне кажется, что я его упускаю. Может кто-нибудь объяснить, какое из многих сложных правил разрешения перегрузки вызывает это, или это что-то еще?
EDIT Я только что обнаружил, что это еще более странно. Даже если foo
внутри пространства имен совсем не соответствует , он все равно не будет использовать его снаружи. Это просто полностью не компилируется:
#include <iostream>
void foo(int) { std::cout << "int\n"; }
namespace NS {
void foo(float, float) { std::cout << "float\n"; }
void bar() {
foo(0);
}
}
int main() {
NS::bar();
}