[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.c++

SFINAE and explicit instantiation

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

4 Answers

greek_bill

11/22/2008 11:33:00 PM

0

On a side note, the above is not actually a partial template function
specialization. It is function overloading. if it was a specialization
(which it couldn't be) it would need to be of the form

template<class A>
void Func<A, float>(A, float)
{}


In any case, this is a side note I think. The original problem is not
affected (I think)!

Francesco

11/24/2008 12:30:00 PM

0

On 23 Nov, 00:32, greek_bill <greek_b...@yahoo.com> wrote:
> On a side note, the above is not actually a partial template function
> specialization. It is function overloading. if it was a specialization
> (which it couldn't be) it would need to be of the form
>
>  template<class A>
> void Func<A, float>(A, float)
> {}
>
> In any case, this is a side note I think. The original problem is not
> affected (I think)!

Hi,
maybe I'm missing something, but from your code it seems that you want
2 functions:
- one that works with a templated argument and an int and
- one that works with a templated argument and a float
so I don't get why you're using SFINAE for that.
Maybe the problem is different so sorry in advance if I sound silly,
but isn't the following doing what you want?
Regards,
Francesco

P.S.
there could be ambiguity if you try to instantiate with a double as
2nd argument but that's another story...

//code
#include <iostream>

template< typename T >
void F( T, int )
{ std::cout << "INT VERSION" << std::endl; }

template< typename T >
void F( T, float )
{ std::cout << "FLOAT VERSION" << std::endl; }

template void F( float, float );

int main()
{
F( 10, 10 );
F( 10, 20.20f );
std::cin.get();
}
//end code

greek_bill

11/26/2008 8:13:00 PM

0

Ugh, I can see why you'd suggest that. I'm afraid that during the
process of simplifying the code to this bare bones example the
usefulness of the SFINAE construct got lost. In the original code that
I was trying to compile the SFINAE construct had a valid purpose and
the code above is the minimal amount of code that I could put together
that reproduces the problem.

As it turns out I've worked around this problem (I expressed the
RestrictTo condition as a compile time assert in the body of the
function), but it would still be interesting to find out why I was
getting the above problem.

Thanks,

Bill

Hendrik Schober

11/27/2008 8:23:00 AM

0

greek_bill wrote:
> 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...

You're not using function template partial specialization, as
this doesn't exist. Instead, you're overloading a function
template. (The existance of the latter is the reason FTPS does
not currently exist.)

> Code as follows :
> [...]

Interesting. VC7.1 compiles your code just fine. VC8 and VC9
give the above error message.

> [...]
> Interestingly, qualifying the explicit specialization with <float>,
> i.e.
>
> template void Func<float>(float, float);
>
>
> doesn' t help matters at all. [...]

It doesn't change the result for VC7.1 and VC8, but makes VC9
run into an internal compiler error. :(

> gcc 4.3.2 compiles this fine by the way.

I'm offline right now and haven't it installed on this machine,
so I can't check, but have you tried Comeau? (IIRC, the URL is
www.comeau.com/tryitout/.) Comeau gives excellent error messages
(and most compiler vendors accept bug reports when accompanied
with "Comeau gives the results I expected").

> Bill

Schobi