以下是一些C++代码:
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的几个重载版本和一个调用f的模板函数g。然后我们在命名空间B中声明了一个新类型,并为该新类型在命名空间A中重载了函数f。使用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)
如果我执行以下任一操作,则代码有效:
- 删除命名空间。
- 将B::C的f重载移动到命名空间B中(感谢Koenig查找)。
- 将B::C及其f重载的声明移到g()的定义之前。
我特别困惑于(3),因为我认为重载决议应该独立于声明顺序。这是预期的C++行为吗?