Вот код С++:
namespace A {
int f(int x) { return 0; }
int f(long x) { return 1; }
template<class T> int g(T x) {
return f(x);
}
}
namespace B {
struct C {};
}
namespace A {
int f(B::C x) { return 2; }
}
void h() {
A::g(B::C());
}
В пространстве имен A код объявляет несколько перегрузок функции f и шаблонную функцию g, которая вызывает f. Затем мы объявляем новый тип в пространстве имен B и перегружаем f для нового типа в пространстве имен A. Компиляция с g++ 4.2 дает
order.cpp: In function ‘int A::g(T) [with T = B::C]’:
order.cpp:21: instantiated from here
order.cpp:7: error: no matching function for call to ‘f(B::C&)’
order.cpp:3: note: candidates are: int A::f(int)
order.cpp:4: note: int A::f(long int)
Код работает, если я выполняю одно из следующих действий:
- Удалите пространства имен.
- Переместить перегрузку f для B:: C в пространство имен B (благодаря поиску Koenig).
- Переместить объявление B:: C и его перегрузку над определением g().
Я особенно озадачен (3), так как у меня создалось впечатление, что разрешение перегрузки должно быть независимым от порядка деклараций. Это ожидаемое поведение С++?