Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

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

6 views
Skip to first unread message

Ik Pil

unread,
Dec 8, 2008, 1:06:33 AM12/8/08
to
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
}

Kai-Uwe Bux

unread,
Dec 8, 2008, 1:40:59 AM12/8/08
to
Ik Pil wrote:

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

unread,
Dec 8, 2008, 1:43:16 AM12/8/08
to

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

unread,
Dec 8, 2008, 1:46:19 AM12/8/08
to

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

unread,
Dec 8, 2008, 1:54:23 AM12/8/08
to

void isn't a parameter type.

--
Ian Collins

Ian Collins

unread,
Dec 8, 2008, 2:01:56 AM12/8/08
to

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

unread,
Dec 8, 2008, 2:04:40 AM12/8/08
to
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

unread,
Dec 8, 2008, 2:09:06 AM12/8/08
to

Thank you, very mush!
I love you!

Noah Roberts

unread,
Dec 8, 2008, 11:46:19 AM12/8/08
to
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

unread,
Dec 9, 2008, 5:38:31 AM12/9/08
to
red floyd wrote:

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

unread,
Dec 9, 2008, 9:18:05 AM12/9/08
to
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...@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

red floyd

unread,
Dec 9, 2008, 9:41:55 AM12/9/08
to
Kai-Uwe Bux 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). ...
>
> 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.
>
Ah. Thank you.

mail...@gmail.com

unread,
Dec 11, 2008, 5:12:00 AM12/11/08
to
There are two problems:

1. Here type of f() is "void (*) (void)" and compiler is deducing R
and TT using type of f() which is not possible.
2. For void you need to specialize.


--
Daya

0 new messages