473,396 Members | 1,997 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

metaprogramming solution to recursive function typedef ?

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


Oct 19 '05 #1
21 3820
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
Oct 19 '05 #2
* 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?
Oct 19 '05 #3
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.

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.


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:::functionPt r 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

Oct 19 '05 #4
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)
Oct 19 '05 #5

"Alf P. Steinbach" <al***@start.no> wrote in message
news:43****************@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
Oct 19 '05 #6

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

Oct 19 '05 #7

"Pete Becker" <pe********@acm.org> wrote in message
news:Rc********************@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
Oct 19 '05 #8
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'.

--

Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)
Oct 19 '05 #9
> 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
Oct 19 '05 #10
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).

--

Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)
Oct 19 '05 #11
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.

Oct 19 '05 #12

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.

Oct 19 '05 #13

"Kaz Kylheku" <kk******@gmail.com> wrote in message
news:11**********************@z14g2000cwz.googlegr oups.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
Oct 19 '05 #14
* Roshan Naik:

"Alf P. Steinbach" <al***@start.no> wrote in message
news:43****************@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.


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?

--
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?
Oct 20 '05 #15
In article <43********@usenet01.boi.hp.com>,
Roshan Naik <na********@gmail.com> wrote:
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 ?


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?
Oct 20 '05 #16
>
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
Oct 20 '05 #17
* 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?


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.

--
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?
Oct 20 '05 #18
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
Oct 20 '05 #19
* Roshan Naik:
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 );


That makes, if possible, even less sense.

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

--
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?
Oct 21 '05 #20

"Alf P. Steinbach" <al***@start.no> wrote in message
news:43****************@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
Oct 21 '05 #21
* 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.

--
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?
Oct 22 '05 #22

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
by: Dave | last post by:
For those who might be so inclined, I was wondering if I might get honest critiques of my first real venture into template metaprogramming. This template metaprogram sorts a list of integers at...
12
by: Dave | last post by:
Would people agree with the statement that to a large degree, using template metaprogramming techniques turns a C++ compiler into a C++ interpreter (but just for the metaprogrammed portions of the...
1
by: mathieu | last post by:
Hello there, I am playing around with template metaprograming: I am trying to redefines my own types. But I am facing a small issue, where I cannot describe the whole implementation in one...
8
by: birchb | last post by:
While working on type expressions I am rather stuck for a way to express recursive types. A simple example of this is a singly-linked list of integers. In some languages you have compiler syntax...
5
by: Mark Stijnman | last post by:
I am trying to teach myself template metaprogramming and I have been trying to create lists of related types. I am however stuck when I want to make a template that gives me the last type in a...
9
by: PengYu.UT | last post by:
Hi, I have the code below this email. I want to replace the last 4 lines with a Metaprogramming loop to get something like the following (I don't know the syntax). Is it possible? for type in...
4
by: Alan Woodland | last post by:
I've been trying out more template metaprogramming ideas with typelists (mostly for personal learning, I'm aware boost most probably provides this facility already), and I've run into this small...
3
by: stdlib99 | last post by:
Hi, I have a simple question regarding templates and meta programming. I am going to try and work my way through the C++ Template Metaprogramming, a book by David Abrahams and Aleksey...
12
by: nooneinparticular314159 | last post by:
Hello. If I declare the following: template<int a, int b, int SomeArray> class DoSomething{ public: .. .. ..
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.