考虑一下我在 IBM 网站上找到的这个例子:
#include <iostream>
using namespace std;
void f(double) { cout << "Function f(double)" << endl; }
template<class T> void g(T a) {
f(123);
h(a);
}
void f(int) { cout << "Function f(int)" << endl; }
void h(double) { cout << "Function h(double)" << endl; }
void i() {
extern void h(int);
g<int>(234);
}
void h(int) { cout << "Function h(int)" << endl; }
int main(void) {
i();
}
它会打印什么?
我改编此示例的 IBM 文档(可在此处获得)说它将打印:
Function f(double) Function h(double)
这样做的理由是依赖于模板参数的名称查找是在 的实例化之前执行的
i()
,所以它找到h(double)
但没有找到h(int)
。当我使用 GCC 4.4.1 编译它时,它会打印:
Function f(double) Function h(int)
GCC 似乎在编译其他所有内容后都在模板中查找与模板参数相关的名称,因此它同时找到
h(double)
andh(int)
,并且更喜欢后者。当我使用 Clang 2.8 编译它时,它无法编译。编译器错误是:
ibm_example.cc:8:3: error: use of undeclared identifier 'h' h(a); ^ ibm_example.cc:16:3: note: in instantiation of function template specialization 'g<int>' requested here g<int>(234); ^ 1 error generated.
Clang 似乎在声明模板的位置查找模板中依赖于模板参数的名称,因此它既没有找到也
h(double)
没有找到h(int)
。
哪一个是对的?