[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.c++

restrict_to, enable_if, etc

greek_bill

10/6/2008 7:16:00 PM

With regards to using Boost enable_if and similar SFINAE constructs,
is it right that you can only put an enable_if on the return type or
as an additional parameter? Why is that?

The following doesn't compile (VC8 and gcc 3.4.4) :

namespace Test
{

template<typename T, typename U>
struct IsSameType
{
enum { value = false };
};

template<typename T>
struct IsSameType<T,T>
{
enum { value = true };
};

//------------------------------------------------------------------

struct Foo
{
// Doesn't compile
template<class T>
void Func(typename enable_if_c<!IsSameType<T, int>::value, T>::type
t)
{}

// But this does...
template<class T>
typename enable_if_c<!IsSameType<T, int>::value, void>::type Func(T
t)
{}

void Func(int i)
{}
};

void FooFunc()
{
Foo f;

// Should go to non-template version
f.Func(5);

// Should go to template version
char* p;
f.Func(p);
}

}


Thanks,

Vassilis
3 Answers

Gennaro Prota

10/6/2008 8:41:00 PM

0

greek_bill wrote:
> With regards to using Boost enable_if and similar SFINAE constructs,
> is it right that you can only put an enable_if on the return type or
> as an additional parameter? Why is that?
>
> The following doesn't compile (VC8 and gcc 3.4.4) :
>
> namespace Test
> {
>
> template<typename T, typename U>
> struct IsSameType
> {
> enum { value = false };
> };
>
> template<typename T>
> struct IsSameType<T,T>
> {
> enum { value = true };
> };
>
> //------------------------------------------------------------------
>
> struct Foo
> {
> // Doesn't compile
> template<class T>
> void Func(typename enable_if_c<!IsSameType<T, int>::value, T>::type
> t)
> {}
>
> // But this does...
> template<class T>
> typename enable_if_c<!IsSameType<T, int>::value, void>::type Func(T
> t)
> {}
>
> void Func(int i)
> {}
> };
[more code snipped]

This is really odd. Please, copy-and-paste the exact code you are trying
to compile (the above can't be it, of course).

--
Gennaro Prota | name.surname yahoo.com
Breeze C++ (preview): <https://sourceforge.net/projects/b...
Do you need expertise in C++? I'm available.

greek_bill

10/7/2008 6:25:00 PM

0

while copying and pasting I missed out the definition of enable_if_c,
which I have it as :

template<bool b, class T>
struct enable_if_c
{
typedef T type;
};

template<class T>
struct enable_if_c<false, T> {};



but other than that it the above code should be enough to illustrate
the problem. You need to comment out one or the other template
implementation of Func().

Gennaro Prota

10/8/2008 7:13:00 PM

0

greek_bill wrote:
> You need to comment out one or the other template
> implementation of Func().

That's the info you should have given :-)

About your original question, you *can* have one function parameter and
enable_if on it (its type), but you'll usually face another issue:
something like

foo< ... >::

is a so-called "non-deduced context". A "classical" example is:

template< typename T >
struct identity
{
typedef T type ;
} ;

template< typename T >
void
f( typename identity< T >::type t )
{
}

int main()
{
f( 1 ) ; // can't deduce
}

So, even if you had simply

struct Foo
{
template< typename T >
void Func( typename enable_if_c< true, T >::type )
{
}
} ;

it wouldn't work for your p (FWIW, f.Func< char * >( p ) would,
instead). On the contrary, your second template gives a way to deduce an
argument for T; and, after all arguments are deduced, they are
substituted in non-deduced contexts (later, SFINAE applies).

--
Gennaro Prota | name.surname yahoo.com
Breeze C++ (preview): <https://sourceforge.net/projects/b...
Do you need expertise in C++? I'm available.