[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.c++

C++ Template metaprogramming : Why this code can't compile?

Ik Pil

12/8/2008 6:07:00 AM

template <typename R, typename TT>
class FuncObject
{
typedef R ( *func_ptr )( TT );
public:
FuncObject( func_ptr p )
: p_( p )
{
}
private:
func_ptr p_;
};



template <typename R, typename TT>
FuncObject<R, TT> func_wrapper( R ( *pfunc )( TT ) )
{
return FuncObject<R, TT>( pfunc );
}



void f( void )
{
}



int main( void )
{
func_wrapper( f ); // can't
}
16 Answers

Kai-Uwe Bux

12/8/2008 6:41:00 AM

0

Ik Pil wrote:

> template <typename R, typename TT>
> class FuncObject
> {
> typedef R ( *func_ptr )( TT );
> public:
> FuncObject( func_ptr p )
> : p_( p )
> {
> }
> private:
> func_ptr p_;
> };
>
>
>
> template <typename R, typename TT>
> FuncObject<R, TT> func_wrapper( R ( *pfunc )( TT ) )
> {
> return FuncObject<R, TT>( pfunc );
> }
>
>
>
> void f( void )
> {
> }
>
>
>
> int main( void )
> {
> func_wrapper( f ); // can't
> }

The templates FuncObject and func_wrapper expect a pointer to a function of
one argument. The Function f takes no arguments. Therefore, you have a
mismatch.


Best

Kai-Uwe Bux

red floyd

12/8/2008 6:43:00 AM

0

Ik Pil wrote:
> template <typename R, typename TT>
> class FuncObject
> {
> typedef R ( *func_ptr )( TT );
> public:
> FuncObject( func_ptr p )
> : p_( p )
> {
> }
> private:
> func_ptr p_;
> };
>
>
>
> template <typename R, typename TT>
> FuncObject<R, TT> func_wrapper( R ( *pfunc )( TT ) )
> {
> return FuncObject<R, TT>( pfunc );
> }
>
>
>
> void f( void )
> {
> }
>
>
>
> int main( void )
> {
> func_wrapper( f ); // can't
> }

This is not metaprogramming, just template programming.
You can also minimize the example by removing all references to
FuncObject.

And it doesn't work for me, either with g++ 3.4.4 or with Comeau
online. I can't figure out why. It complains that there's no
match, even when I pass &f instead of just f.

red floyd

12/8/2008 6:46:00 AM

0

Kai-Uwe Bux wrote:
> Ik Pil wrote:
>
>> template <typename R, typename TT>
>> class FuncObject
>> {
>> typedef R ( *func_ptr )( TT );
>> public:
>> FuncObject( func_ptr p )
>> : p_( p )
>> {
>> }
>> private:
>> func_ptr p_;
>> };
>>
>>
>>
>> template <typename R, typename TT>
>> FuncObject<R, TT> func_wrapper( R ( *pfunc )( TT ) )
>> {
>> return FuncObject<R, TT>( pfunc );
>> }
>>
>>
>>
>> void f( void )
>> {
>> }
>>
>>
>>
>> int main( void )
>> {
>> func_wrapper( f ); // can't
>> }
>
> The templates FuncObject and func_wrapper expect a pointer to a function of
> one argument. The Function f takes no arguments. Therefore, you have a
> mismatch.
>

Kai-Uwe, can you tell me what's worng with this one? Is it the same
issue, even when I explicitly specify void?

template <typename R, typename TT>
void func_wrapper( R ( *pfunc )( TT ) )
{
}

void f( )
{
}

int main( )
{
func_wrapper<void,void>( &f ); // can't
}

Ian Collins

12/8/2008 6:54:00 AM

0

red floyd wrote:
> Kai-Uwe Bux wrote:
>> Ik Pil wrote:
>>
>>> template <typename R, typename TT>
>>> class FuncObject
>>> {
>>> typedef R ( *func_ptr )( TT );
>>> public:
>>> FuncObject( func_ptr p )
>>> : p_( p )
>>> {
>>> }
>>> private:
>>> func_ptr p_;
>>> };
>>>
>>>
>>>
>>> template <typename R, typename TT>
>>> FuncObject<R, TT> func_wrapper( R ( *pfunc )( TT ) )
>>> {
>>> return FuncObject<R, TT>( pfunc );
>>> }
>>>
>>>
>>>
>>> void f( void )
>>> {
>>> }
>>>
>>>
>>>
>>> int main( void )
>>> {
>>> func_wrapper( f ); // can't
>>> }
>>
>> The templates FuncObject and func_wrapper expect a pointer to a
>> function of
>> one argument. The Function f takes no arguments. Therefore, you have a
>> mismatch.
>>
>
> Kai-Uwe, can you tell me what's worng with this one? Is it the same
> issue, even when I explicitly specify void?
>
> template <typename R, typename TT>
> void func_wrapper( R ( *pfunc )( TT ) )
> {
> }
>
> void f( )
> {
> }
>
> int main( )
> {
> func_wrapper<void,void>( &f ); // can't
> }

void isn't a parameter type.

--
Ian Collins

Ian Collins

12/8/2008 7:02:00 AM

0

Ik Pil wrote:
> template <typename R, typename TT>
> class FuncObject
> {
> typedef R ( *func_ptr )( TT );
> public:
> FuncObject( func_ptr p )
> : p_( p )
> {
> }
> private:
> func_ptr p_;
> };
>
> template <typename R, typename TT>
> FuncObject<R, TT> func_wrapper( R ( *pfunc )( TT ) )
> {
> return FuncObject<R, TT>( pfunc );
> }
>
> void f( void )
> {
> }
>
> int main( void )
> {
> func_wrapper( f ); // can't
> }

You can't use void as a function parameter type in this way. You will
have to specialise your object and function for functions with no
parameters.

There isn't any metaprogramming in your code.

--
Ian Collins

Ian Collins

12/8/2008 7:05:00 AM

0

Ian Collins wrote:

> red floyd wrote:
>>
>> template <typename R, typename TT>
>> void func_wrapper( R ( *pfunc )( TT ) )
>> {
>> }
>>
>> void f( )
>> {
>> }
>>
>> int main( )
>> {
>> func_wrapper<void,void>( &f ); // can't
>> }
>
> void isn't a parameter type.
>
I though I'd better try it and I added a specialisation for func_wrapper
only:

template <typename R>
FuncObject<R,void> func_wrapper( R ( *pfunc )() )
{
return FuncObject<R,void>( pfunc );
}

Which gives a more helpful error message from Sun CC:

line 4: Warning (Anachronism): A typedef for "void" is not a valid way
to declare a function without arguments.

--
Ian Collins

Ik Pil

12/8/2008 7:09:00 AM

0

On 12?8?, ??3?40?, Kai-Uwe Bux <jkherci...@gmx.net> wrote:
> Ik Pil wrote:
> > template <typename R, typename TT>
> > class FuncObject
> > {
> > typedef R ( *func_ptr )( TT );
> > public:
> > FuncObject( func_ptr p )
> > : p_( p )
> > {
> > }
> > private:
> > func_ptr p_;
> > };
>
> > template <typename R, typename TT>
> > FuncObject<R, TT> func_wrapper( R ( *pfunc )( TT ) )
> > {
> > return FuncObject<R, TT>( pfunc );
> > }
>
> > void f( void )
> > {
> > }
>
> > int main( void )
> > {
> > func_wrapper( f ); // can't
> > }
>
> The templates FuncObject and func_wrapper expect a pointer to a function of
> one argument. The Function f takes no arguments. Therefore, you have a
> mismatch.
>
> Best
>
> Kai-Uwe Bux

Thank you, very mush!
I love you!

john

12/8/2008 4:46:00 PM

0

You got your answer but I'd also seriously suggest that unless you're
doing this as an intellectual exercise that you use boost::function in
combination with boost::bind. The authors have already gone to the work
of addressing a lot of touchy concerns that would end up biting you in
the neck.

Kai-Uwe Bux

12/9/2008 10:39:00 AM

0

red floyd wrote:

> Kai-Uwe Bux wrote:
>> Ik Pil wrote:
>>
>>> template <typename R, typename TT>
>>> class FuncObject
>>> {
>>> typedef R ( *func_ptr )( TT );
>>> public:
>>> FuncObject( func_ptr p )
>>> : p_( p )
>>> {
>>> }
>>> private:
>>> func_ptr p_;
>>> };
>>>
>>>
>>>
>>> template <typename R, typename TT>
>>> FuncObject<R, TT> func_wrapper( R ( *pfunc )( TT ) )
>>> {
>>> return FuncObject<R, TT>( pfunc );
>>> }
>>>
>>>
>>>
>>> void f( void )
>>> {
>>> }
>>>
>>>
>>>
>>> int main( void )
>>> {
>>> func_wrapper( f ); // can't
>>> }
>>
>> The templates FuncObject and func_wrapper expect a pointer to a function
>> of one argument. The Function f takes no arguments. Therefore, you have a
>> mismatch.
>>
>
> Kai-Uwe, can you tell me what's worng with this one? Is it the same
> issue, even when I explicitly specify void?
>
> template <typename R, typename TT>
> void func_wrapper( R ( *pfunc )( TT ) )
> {
> }
>
> void f( )
> {
> }
>
> int main( )
> {
> func_wrapper<void,void>( &f ); // can't
> }

Yes, it's the same.

The standard has a rather vague provison in [8.5.3/2]

...The parameter list (void) is equivalent to the empty parameter list.
Except for this special case, void shall not be a parameter type (though
types derived from void, such as void*, can). ...

but it also has something that undoubtedly applies: a provision for when
type deduction fails. In [14.8.2/2] it says:

... Type deduction may fail for the following reasons:
...
- Attempting to create a function type in which a parameter has a
type of void.


Best

Kai-Uwe Bux

James Kanze

12/9/2008 2:18:00 PM

0

On Dec 9, 11:38 am, Kai-Uwe Bux <jkherci...@gmx.net> wrote:
> red floyd wrote:

[...]
> > Kai-Uwe, can you tell me what's worng with this one? Is it
> > the same issue, even when I explicitly specify void?

> > template <typename R, typename TT>
> > void func_wrapper( R ( *pfunc )( TT ) )
> > {
> > }

> > void f( )
> > {
> > }

> > int main( )
> > {
> > func_wrapper<void,void>( &f ); // can't
> > }

> Yes, it's the same.

> The standard has a rather vague provison in [8.5.3/2]

> ...The parameter list (void) is equivalent to the empty parameter list.
> Except for this special case, void shall not be a parameter type (though
> types derived from void, such as void*, can). ...

Most importantly, in this case, void is not a type; it's just a
keyword with a special meaning. Thus, something like:

typedef void toto ;
void f( toto ) ;

is not legal.

> but it also has something that undoubtedly applies: a
> provision for when type deduction fails. In [14.8.2/2] it
> says:

> ... Type deduction may fail for the following reasons:

> - Attempting to create a function type in which a parameter has a
> type of void.

Exactly. Because a parameter cannot have the type void.

--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34