On 2012-05-10 10:14, David Barrett-Lennard wrote:
> Under VS2008, VS2010 I get this behaviour:
>
> template<typename T> struct X { typedef T type; };
>
> void f(double) {}
> template<typename T> void f(T) {}
>
> void g(double) {}
> template<typename T> void g(typename X<T>::type) {}
>
> void test()
> {
> f(1); // picks f(T)
> g(1); // picks g(double)
> }
>
> Is it a bug, or expected?
This is expected. Keep in mind that within typename X<T>::type
T is a non-deduced context: It is in general impossible for a compiler
to find a type T given a member type of a template X. In your example
template g does not participate in overload resolution, because
deduction fails, therefore the function g(double) will be selected.
> Either way, how can one use enable_if effectively?
I don't understand you question. enable_if is always used, when
deduction has already taken place, e.g. rewrite g as (I assume that X
represents enable_if here):
template<typename T>
typename enable_if</some_condition on T/, void>::type g(T) {}
or as
template<typename T>
void g(T, typename enable_if</some_condition on T/, void>::type* = 0) {}
Since C++11 new forms are possible taking advantage of default template
arguments of function templates:
template<typename T,
typename = typename enable_if</some_condition on T/, void>::type>
void g(T) {}
or
template<typename T,
typename enable_if</some_condition on T/, void>::type* = 0>
void g(T) {}
HTH & Greetings from Bremen,
Daniel Krügler