Article View: comp.std.c++
Article #1156Re: C++ already *has* nested functions SO WHAT'S THE BEEF?
From: Christophe GROSJEAN
Date: Thu, 24 Dec 1992 11:38
Date: Thu, 24 Dec 1992 11:38
226 lines
5901 bytes
5901 bytes
The following code shows another way of simulating nested functions.
That's what I use right now, waiting for the removing of this restriction.
I've read that GNU support nested functions, the compiler I use right know
(G++ 2.3.2) does not seem to do it. Which version does it ?
Sample (should say simple) code follow-up, with context. Use of templates is not
relevant to the nested function problem.
The syntax could be *much* simplified using macros. But stantard macro preprocessors
are not powerful enough.
First, anybody thought of removing the comma-as-separator restriction
in the preprocessor in order you can choose the right one ?
I had much trouble with that using macros with multi-arguments templated classes. 'cause of that.
Second, overloading should be extended to macros in C++, seems homogeneous, and
usefull.
Third, in my case, what I would need is context vars, stacking vars in a first macro then
using them in a second one, kind of parenthesing macros.
--------- code follows -------------
#include <iostream.h>
#define TRUE 1
#define FALSE 0
template<class R, class T>
class Func1
{
public:
virtual R call(T o1) = 0;
};
void * ONULL = NULL;
template<class DATA>
class List
{
public:
List(void) {init();}
List(DATA o1){ init(); add(o1);}
List(DATA o1, DATA o2){init(); add(o1); add(o2);}
List(DATA o1, DATA o2, DATA o3){
init(); add(o1); add(o2); add(o3);}
List(DATA o1, DATA o2, DATA o3, DATA o4){
init(); add(o1); add(o2); add(o3); add(o4);}
void add(DATA o1){
Link * tmp = new Link;
tmp->next = head;
tmp->data = o1;
head = tmp;
}
void addAll(List<DATA> & c1) {
class p : public Func1<void,DATA> {
public:
p(List<DATA> & c) : c(c) {}
void call(DATA i) {c.add(i);}
List<DATA> & c;
} p(*this);
c1.all(p);
}
void all(Func1<void,DATA> & p){
Link * tmp;
for(tmp=head;tmp != NULL;tmp=tmp->next)
p.call(tmp->data);
}
DATA & any(Func1<int,DATA> & t){
Link * tmp;
for(tmp=head;tmp != NULL;tmp=tmp->next)
if (t.call(tmp->data))
return tmp->data;
error = 1;
return (DATA &)ONULL;
}
void unlink_any(Func1<int, DATA> & t){
if (head == NULL){error = 1;return;}
else{
Link * tmp = head;
if (t.call(tmp->data)){
head = tmp->next;
delete tmp;
return;
}
else {
Link * tmp2;
for (tmp2 = tmp->next; tmp2 != NULL;tmp2=(tmp=tmp2)->next)
if (t.call(tmp2->data)){
tmp->next = tmp2->next;
delete tmp2;
return;
}
}
}
error = 1;
return;
}
void unlink_all(Func1<int, DATA> & t){
Link * tmp;
Link * tmp2;
tmp = head;
head = NULL;
while(tmp != NULL){
tmp2 = tmp;
tmp = tmp->next;
if (t.call(tmp2->data))
{
delete tmp2;
}
{
tmp2->next = head;
head = tmp2;
}
}
reverse();
}
int includes(Func1<int, DATA> & t){
Link * tmp;
for(tmp=head;tmp != NULL;tmp=tmp->next)
if (t.call(tmp->data))
return TRUE;
return FALSE;
}
int occurencesOf(Func1<int, DATA> & t)
{
int nb = 0;
for(Link * tmp=head;tmp != NULL;tmp=tmp->next)
if( t.call(tmp->data)) nb++;
return nb;
}
private:
void init(void) { head = (Link *)NULL;}
void reverse(){
Link * tmp;
Link * tmp2;
tmp = head;
head = NULL;
while(tmp != NULL){
tmp2 = tmp->next;
tmp->next = head;
head = tmp;
tmp = tmp2;
}
}
struct Link
{
Link * next;
DATA data;
} * head;
int error;
};
int main()
{
class pint : public Func1<void,int>
{
public:
pint(void) {}
void call(int d) { cout << d << " "; }
} pint;
class pchar : public Func1<void,char>
{
public:
pchar(void) {}
void call(char d) { cout << d << " "; }
} pchar;
class t1 : public Func1<int,int>
{
public:
t1(void) {}
int call(int d) {return (d>=200);}
} t1;
int toto = 120;
// Function reading context variable toto (value a this point)
class t2 : public Func1<int,int>
{
public:
t2(int toto) : toto(toto) {}
int call(int d) {return (d > toto);}
int toto;
} t2(toto);
// Function using context variable toto (whatever value)
class t3 : public Func1<int,int>
{
public:
t3(int & toto) : toto(toto) {}
int call(int d) {return (d <= toto);}
int & toto;
} t3(toto);
// Function modifying context variable max
int max;
class getmax : public Func1<void, int>
{
public:
getmax(int & max) : max(max) {}
void call(int d) { max = (max > d)?max:d; }
int & max;
} getmax(max);
List<char> L3('A','B','C');
List<int> L1(100,120,130), L2(200);
L1.add(110); L2.add(210);
L1.addAll(L2); L1.add(140); L1.add(150); L1.add(160);
cout << "List L1 : "; L1.all(pint); cout << "\n";
cout << "List L2 : "; L2.all(pint); cout << "\n";
cout << "List L3 : "; L3.all(pchar); cout << "\n";
toto = 140;
cout << "First elt of L1 veryfying elt >= 200 : " << L1.any(t1) << "\n";
cout << "First elt of L1 veryfying elt > toto (120) : " << L1.any(t2) << "\n";
cout << "First elt of L1 veryfying elt <= toto (now=140) : " << L1.any(t3) << "\n";
L1.all(getmax);
cout << "Max elt of L1 : " << max << "\n";
return 0;
}
-------- end of code --------
Technical Details
Message-ID:
<KRISS.92Dec24123825@roll.ibp.fr>Path:
arc1-ca.pugleaf.net!sparky!uunet!mcsun!julienas!jussieu!shiva.jussieu.fr!krissReferences:
<1992Dec21.080952.15309@netcom.com> <1992Dec23.165719.13021@ucc.su.OZ.AU>Show Full Headers
Complete Article Headers
Newsgroups: comp.std.c++ Path: arc1-ca.pugleaf.net!sparky!uunet!mcsun!julienas!jussieu!shiva.jussieu.fr!kriss From: kriss@roll.ibp.fr (Christophe GROSJEAN) Subject: Re: C++ already *has* nested functions SO WHAT'S THE BEEF? In-Reply-To: maxtal@extro.ucc.su.OZ.AU's message of Wed, 23 Dec 1992 16:57:19 GMT Message-ID: <KRISS.92Dec24123825@roll.ibp.fr> Sender: news@jussieu.fr (Le Facteur) Nntp-Posting-Host: roll.ibp.fr Reply-To: grosjean@masi.ibp.fr Organization: Laboratoire MASI, Paris, France. References: <1992Dec21.080952.15309@netcom.com> <1992Dec23.165719.13021@ucc.su.OZ.AU> Date: Thu, 24 Dec 1992 11:38:25 GMT Lines: 226