greek_bill
11/21/2008 9:45:00 PM
Hi,
I have a template function for which I use SFINAE to restrict one of
the parameters. Then I also have a partial specialization[1] of this
function.I would like to provide an explicit instantiation of the
partially specialized version, but my compiler (VC8) complains because
it fails the SFINAE version.
[1] I just realized as I was typing this that I'm using partial
_function_ specialization. I'm sure I remember reading somewhere that
this isn't allowed. VC8 and gcc are quite happy with it though.
Anyway...
Code as follows :
// Used for the SFINAE condition
template<typename T, typename U>
struct IsSameType { enum { value = false }; };
template<typename T>
struct IsSameType<T,T> { enum { value = true }; };
// SFINAE helper
template<bool allow, class T>
struct RestrictTo {};
template<class T>
struct RestrictTo<true, T> { typedef T type; };
// SFINAE function template
class Foo {};
template<class A, class T>
typename RestrictTo<IsSameType<T,int>::value, void>::type
Func(A, T)
{}
// Partially specialized version
template<class A>
void Func(A, float)
{}
// Explicit instantiation
template void Func(float, float);
This compiles fine with g++. VC8 says :
error C2794: 'type' : is not a member of any direct or indirect base
class of 'RestrictTo<allow,T>'
with
[
allow=false,
T=void
]
As I understand it, if I was to just call Func(1.0f, 2.0f) then SFINAE
would kick in an reject the first version, leading to the specialized
version to be picked up. If I didn't have SFINAE then there would be
an ambiguity.
It seems though that this rule isn't follow if I try to do an explicit
instantiation. It looks like the compiler thinks that I'm trying to
explicitly instantiate the SFINAE version with an argument that
violates the condition I specified.
Interestingly, qualifying the explicit specialization with <float>,
i.e.
template void Func<float>(float, float);
doesn' t help matters at all. I was hoping that if I supply <float>
that would be enough of a hint to the compiler that I'm trying to
instantiate a template with just one parameter.
gcc 4.3.2 compiles this fine by the way.
Thanks,
Bill