Рассмотрим этот пример, который я нашел на веб-сайте 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)
, так иh(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)
.
Какой из них прав?