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

metaprogramming solution to recursive function typedef ?

3 views
Skip to first unread message

Roshan Naik

unread,
Oct 19, 2005, 4:14:44 AM10/19/05
to
typedef int foo ( foo ); // foo is a pointer-to-function type that takes
another foo as argument and returns an int

I need to achieve the above effect somehow. This is not accepted by any
compiler I have tried, even though I cant spot anything in the standard that
restricts it.

Is there a way to achieve this typedefintion using metaprogramming ? I
noticed that boost::variant does some metaprogramming tricks to allow

variants to be contained in variants. But it is unclear to me how that is
acheived, also that problem _may_ not be exactly the same as this.

-Roshan Naik


Kai-Uwe Bux

unread,
Oct 19, 2005, 4:23:20 AM10/19/05
to
Roshan Naik wrote:

> typedef int foo ( foo ); // foo is a pointer-to-function type that takes
> another foo as argument and returns an int
>
> I need to achieve the above effect somehow.

What is the real underlying problem that you are trying to solve?

[snip]


Best

Kai-Uwe Bux

Alf P. Steinbach

unread,
Oct 19, 2005, 4:36:16 AM10/19/05
to
* Roshan Naik:

> typedef int foo ( foo ); // foo is a pointer-to-function type that takes
> another foo as argument and returns an int
>
> I need to achieve the above effect somehow.

struct Foo
{
virtual int operator()( Foo const* ) const = 0;
};

Then if you need to pass such functors by value, you can wrap them in a
functor with a smart-pointer to the actual functor.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?

Greg

unread,
Oct 19, 2005, 5:19:47 AM10/19/05
to

Perhaps you want something along these lines:

template <class T>
struct CallFunctionPtr
{
typedef int (*functionPtr)(T);

typedef CallFunctionPtr<fPtr> next;
};

int main()
{
CallFunctionPtr<int(*)()>::next::functionPtr fPtr;

// fPtr is of type int (*)(int (*)())

CallFunctionPtr<int(*)()>::next::next:::functionPtr f2Ptr;

// f2Ptr is of type int (*)(int (*)(int (*)()))
}

Each "next" inner type corresponds to a function call to a function
whose pointer is being passed as a parameter. The number of "next"'s
that are chained together equals how many functions will be called
before the nested function pointers are exhausted.

Greg

Pete Becker

unread,
Oct 19, 2005, 7:57:22 AM10/19/05
to
Roshan Naik wrote:
> typedef int foo ( foo ); // foo is a pointer-to-function type that takes
> another foo as argument and returns an int
>

The comment is incorrect, for two reasons. First, foo is not defined,
because this is not a valid declaration. But you knew that. <g>

Second, if the argument type were changed from foo to, say, int, then
foo would not be a pointer to function type. It would be a function type.

--

Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)

Roshan Naik

unread,
Oct 19, 2005, 1:00:28 PM10/19/05
to

"Alf P. Steinbach" <al...@start.no> wrote in message
news:4356050b....@news.individual.net...

> struct Foo
> {
> virtual int operator()( Foo const* ) const = 0;
> };
>
> Then if you need to pass such functors by value, you can wrap them in a
> functor with a smart-pointer to the actual functor.
>

Thanks. But I already considered that and i need to have a real function
type. So i can use more
terse syntax like this...

int myFunc1 ( foo arg) {
//. ..
}

instead of having to write classes deriving from Foo and then implementing
( ) as a member function.

-Roshan


Dan Cernat

unread,
Oct 19, 2005, 1:13:41 PM10/19/05
to

Roshan Naik wrote:
> typedef int foo ( foo ); // foo is a pointer-to-function type that takes
> another foo as argument and returns an int
>
<snip>

so foo is
a pointer to a function that has as a sole argument
a pointer to a function that has as a sole argument
a pointer to a function that has as a sole argument
.....

/dan

Roshan Naik

unread,
Oct 19, 2005, 1:57:02 PM10/19/05
to

"Pete Becker" <peteb...@acm.org> wrote in message
news:RcydnVcx9sA...@rcn.net...

> Roshan Naik wrote:
> > typedef int foo ( foo ); // foo is a pointer-to-function type that
takes
> > another foo as argument and returns an int
> >
>
> The comment is incorrect, for two reasons. First, foo is not defined,
> because this is not a valid declaration. But you knew that. <g>

Please elaborate. I assume that the above declaration (if it would be
accpeted by any compiler)
would be equivalent to.....
typedef int (*foo) (foo);

Note that I can use A* within the declaration of class A. Thus foo here
doesnt have to be defined as its a pointer type (my way of thinking).

> Second, if the argument type were changed from foo to, say, int, then
> foo would not be a pointer to function type. It would be a function type.

Is there such a thing as "function type" for variables in C++ ? It is my
understanding that you can only
have a pointers/references to functions. There is no way to define a
value-type variable that holds a function.
You can only declare a pointer-type variable that stores the address of a
function.

A function itself has a "function type" but from the standpoint of declaring
a variable/parameter
we have to use pointer to function types.

-Roshan


Pete Becker

unread,
Oct 19, 2005, 2:14:19 PM10/19/05
to
Roshan Naik wrote:
>
> A function itself has a "function type" but from the standpoint of declaring
> a variable/parameter
> we have to use pointer to function types.
>

In C that is correct. In C++ you can also create a reference to function
type, although that's of minor utility. Nevertheless, in both C and C++,
typedef int foo(int); defines a function type, not a pointer to function
type. To define a pointer to function type you need a *, which says
'pointer'.

Roshan Naik

unread,
Oct 19, 2005, 2:58:40 PM10/19/05
to
> In C that is correct. In C++ you can also create a reference to function
> type, although that's of minor utility. Nevertheless, in both C and C++,
> typedef int foo(int); defines a function type, not a pointer to function
> type. To define a pointer to function type you need a *, which says
> 'pointer'.

And of what use is a function type ?

-Roshan


Pete Becker

unread,
Oct 19, 2005, 4:47:12 PM10/19/05
to
Roshan Naik wrote:
>
> And of what use is a function type ?
>

Well, you can declare a pointer to that type:

typedef int foo(int);
typedef foo *foo_ptr;

Of course, most people do that all in one declaration. In C it's pretty
much pointless. In C++, though, it can be used to define the signature
of a member operator() of a template:

template <class Ftype>
struct function
{
Ret operator()(T1&, T2&, ..., TN&);
};

There's a lot of mechanism missing from that definiton, obviously
(needed to split Ftype to figure out what Ret, T1, T2, etc. really are).
But it's essentially what TR1's function template looks like:

#include <functional>
#include <math.h>
using std::tr1::function;

typedef float ft(float);
function<ft> func(fsin);

now func(1.0) returns fsin(1.0).

func = fcos;

now func(1.0) returns fcos(1.0).

Message has been deleted

Kaz Kylheku

unread,
Oct 19, 2005, 5:45:27 PM10/19/05
to

Roshan Naik wrote:
> typedef int foo ( foo ); // foo is a pointer-to-function type that takes
> another foo as argument and returns an int
>
> I need to achieve the above effect somehow. This is not accepted by any
> compiler I have tried, even though I cant spot anything in the standard that
> restricts it.

What restricts it is that scope of the identifier foo begins after the
declarator that introduces it.

> Is there a way to achieve this typedefintion using metaprogramming ?

You have to use a type which allows for forward references. This means
you have to use a struct or class, like this. Let's do it in a C89
compatible way:

/* introduce incomplete type */
struct foo_struct;

/* foo_fun is a pointer to a function that takes a foo_struct */
typedef int (*foo_fun)(struct foo_struct);

/* and a foo struct contains a pointer to a foo_fun */
struct foo_struct {
foo_fun fun;
};

/* here is a foo_fun compatible function */
int foo_fun_impl(struct foo_struct s)
{
struct foo_struct self = { foo_fun_impl };

if (s.fun != foo_fun_impl)
s.fun(self);
}

> I
> noticed that boost::variant does some metaprogramming tricks to allow
>
> variants to be contained in variants. But it is unclear to me how that is
> acheived, also that problem _may_ not be exactly the same as this.

There is nothing contained within anything here, because a function
cannot take a function as a parameter, nor can it return a function. So
a function's type cannot have a function type among any of its
constituents.

The above struct trick only overcomes the lexical difficulty, namely
the identifier being declared is not available within its declarator.
There is no semantic problem being overcome.

Suppose you had the following language extension:

typedef incomplete x;

allowing you to assert that x is some completely unspecified type,
which can be completed in any manner whatsoever, not limited to classes
or structures. This could be accompanied by special rules that would
let you write something like:

typedef x (*x)(x);

thereby completing the type x as a pointer to function that takes an x
value and returns an x value.

Roshan Naik

unread,
Oct 19, 2005, 6:56:28 PM10/19/05
to

"Kaz Kylheku" <kkyl...@gmail.com> wrote in message
news:1129758177.8...@z14g2000cwz.googlegroups.com...

> You have to use a type which allows for forward references. This means
> you have to use a struct or class, like this. Let's do it in a C89
> compatible way:
>
> /* introduce incomplete type */
> struct foo_struct;
>
> /* foo_fun is a pointer to a function that takes a foo_struct */
> typedef int (*foo_fun)(struct foo_struct);
>
> /* and a foo struct contains a pointer to a foo_fun */
> struct foo_struct {
> foo_fun *fun;

> }
>
> /* here is a foo_fun compatible function */
> int foo_fun_impl(struct foo_struct s)
> {
> struct foo_struct self = { foo_fun_impl };
>
> if (s.fun != foo_fun_impl)
> s.fun(self);
> }
>

I am familiar with that trick, but what it gives you is a function that
takes a (functor type) struct as parameter instead of a function pointer.
80% there ...but no quite 100%.

I was hoping to be able to do some magic with templates and type
calculations with them to by-pass the compiler
restriction( i cannot definitely say it is a language restriction). But my
attempts so far on finding a solution with metaprogramming have been
unsuccessful.

-Roshan


Alf P. Steinbach

unread,
Oct 19, 2005, 9:57:49 PM10/19/05
to
* Roshan Naik:

Pardon me for asking, but exactly what is it that you think prevents you from
writing simple functions and using them where Foo argument is expected?

Greg Comeau

unread,
Oct 20, 2005, 9:48:09 AM10/20/05
to
In article <43569763$1...@usenet01.boi.hp.com>,

Only but to declare and define and call functions.
--
Greg Comeau / Celebrating 20 years of Comeauity!
Comeau C/C++ ONLINE ==> http://www.comeaucomputing.com/tryitout
World Class Compilers: Breathtaking C++, Amazing C99, Fabulous C90.
Comeau C/C++ with Dinkumware's Libraries... Have you tried it?

Roshan Naik

unread,
Oct 20, 2005, 1:45:31 PM10/20/05
to
>
> Pardon me for asking, but exactly what is it that you think prevents you
from
> writing simple functions and using them where Foo argument is expected?
>

As I dont know what function will be actually called, until runtime.

int myFunc1 ( foo arg) { . .. }
int myFunc2 ( foo arg) { . .. }
int myFunc3 ( foo arg) { . .. }

myFunc1 ( myFunc2 ) ;
myFunc1 ( myFunc3 );

- Roshan Naik


Alf P. Steinbach

unread,
Oct 20, 2005, 2:02:45 PM10/20/05
to
* Roshan Naik:

That doesn't make much sense to me as an argument against using a functor.

Roshan Naik

unread,
Oct 20, 2005, 7:12:38 PM10/20/05
to

> > As I dont know what function will be actually called, until runtime.
> >
> > int myFunc1 ( foo arg) { . .. }
> > int myFunc2 ( foo arg) { . .. }
> > int myFunc3 ( foo arg) { . .. }
> >
> > myFunc1 ( myFunc2 ) ;
> > myFunc1 ( myFunc3 );
>
> That doesn't make much sense to me as an argument against using a functor.

Consider the alternative to above code using functors:

struct myFunc1 : foo {
int operator( ) ( foo arg ) {
...
}
};

struct myFunc2 : foo {
int operator( ) ( foo arg ) {
...
}
};

struct myFunc3 : foo {
int operator( ) ( foo arg ) {
...
}
};

myFunc1 mf1;
myFunc2 mf2;
myFunc3 mf3;

mf1 ( mf2 ) ;
mf1 ( mf3 );


- Roshan Naik


Alf P. Steinbach

unread,
Oct 21, 2005, 1:02:44 AM10/21/05
to
* Roshan Naik:

That makes, if possible, even less sense.

Where did you get the idea that the above is "the" alternative?

Roshan Naik

unread,
Oct 21, 2005, 3:01:48 PM10/21/05
to

"Alf P. Steinbach" <al...@start.no> wrote in message
news:4358764e....@news.individual.net...
> * Roshan Naik:

> That makes, if possible, even less sense.
>
> Where did you get the idea that the above is "the" alternative?

I didnt use the "stress". There may be others and thats what I am looking
for. What I was conveying is ... the argument against functors based
solutions is that (in this case) it leads to more syntax all over the place,
as compared to ...

> > > int myFunc1 ( foo arg) { . .. }
> > > int myFunc2 ( foo arg) { . .. }
> > > int myFunc3 ( foo arg) { . .. }
> > >
> > > myFunc1 ( myFunc2 ) ;
> > > myFunc1 ( myFunc3 );

Other downsides :
- The functors based approach you mentioned requires virtual function table
based dispatching,
- Each usage of a function needs a object, plus the member function
pointer, plus the vtable jazz... unlike the plain functions approach which
would only requires a function pointer.

- Roshan


Alf P. Steinbach

unread,
Oct 22, 2005, 12:57:11 AM10/22/05
to
* Roshan Naik:
> [reasons Why It Can't Be Done Or Any Solution Is Inferior To No Solution]

To get you on track: think about functor objects containing function pointers.

0 new messages