Если вы не укажете параметр T
, компилятор не будет пытаться вычесть T
каким-либо образом.
Даже если вы укажете это явно, я считаю, что это будет работать только там, где предоставляется оригинальное определение, но не typedefs.
Рассмотрим следующий пример (скомпилированный с clang ++, по-видимому, g ++ на этом не работает):
#include <stdio.h>
template <typename T>
void foo(T) {
printf("foo(T)\n");
}
template <typename T>
void foo(typename T::value) {
printf("foo(T::value)\n");
}
struct X {
class value {};
};
struct Z {
typedef int value;
};
struct XZ {
typedef Z value;
};
typedef X::value Xv;
#define CALL(function,param) printf(#function " (" #param ") = "); function(param());
void explicitCalls() {
printf("Explicit calls:\n");
CALL(foo<int>,int);
CALL(foo<X::value>,X::value);
CALL(foo<Z::value>,Z::value);
CALL(foo<XZ::value>,XZ::value);
CALL(foo<Xv>,Xv);
}
void implicitCalls() {
printf("Implicit calls:\n");
CALL(foo,int);
CALL(foo,X::value);
CALL(foo,Z::value);
CALL(foo,XZ::value);
CALL(foo,Xv);
}
int main() {
explicitCalls();
implicitCalls();
}
Вывод:
Explicit calls:
foo<int> (int) = foo(T)
foo<X::value> (X::value) = foo(T::value)
foo<Z::value> (Z::value) = foo(T)
foo<XZ::value> (XZ::value) = foo(T)
foo<Xv> (Xv) = foo(T::value)
Implicit calls:
foo (int) = foo(T)
foo (X::value) = foo(T)
foo (Z::value) = foo(T)
foo (XZ::value) = foo(T)
foo (Xv) = foo(T)