Est-il possible en C ou C ++ de créer une fonction dans un autre?

Quelqu’un pourrait-il me dire si cela est possible en C ou C ++?

void fun_a(); //int fun_b(); ... main(){ ... fun_a(); ... int fun_b(){ ... } ... } 

ou quelque chose de similaire, par exemple une classe dans une fonction?

merci pour vos réponses,

Wow, je suis surpris que personne n’ait dit oui! Les fonctions libres ne peuvent pas être nestedes, mais les foncteurs et les classes en général le peuvent.

 void fun_a(); //int fun_b(); ... main(){ ... fun_a(); ... struct { int operator()() { ... } } fun_b; int q = fun_b(); ... } 

Vous pouvez donner un constructeur au foncteur et passer des références aux variables locales pour le connecter à la scope locale. Sinon, il peut accéder à d’autres types locaux et à des variables statiques. Les classes locales ne peuvent cependant pas être des arguments pour les modèles.

C ++ ne supporte pas les fonctions nestedes, cependant vous pouvez utiliser quelque chose comme boost :: lambda .

C – Oui pour gcc en tant qu’extension .

C ++ – Non.

vous ne pouvez pas créer de fonction dans une autre fonction en C ++.

Vous pouvez cependant créer un foncteur de classe local:

 int foo() { class bar { public: int operator()() { return 42; } }; bar b; return b(); } 

en C ++ 0x, vous pouvez créer une expression lambda:

 int foo() { auto bar = []()->int{return 42;}; return bar(); } 

Non, mais en C ++ 0x, vous pouvez http://en.wikipedia.org/wiki/C%2B%2B0x#Lambda_functions_and_expressions prendre en charge plusieurs années de plus. La norme n’est pas complète au moment d’écrire ces lignes.

-modifier-

Oui

Si vous pouvez utiliser MSVC 2010. J’ai couru le code ci-dessous avec succès

 void test() { []() { cout << "Hello function\n"; }(); auto fn = [](int x) -> int { cout << "Hello function (" << x << " :))\n"; return x+1; }; auto v = fn(2); fn(v); } 

sortie

 Hello function Hello function (2 :)) Hello function (3 :)) 

(J'ai écrit >> c:\dev\loc\uniqueName.txt dans la section des arguments de travail du projet et copié ce résultat)

Le terme que vous recherchez est fonction nestede . Ni le C standard ni le C ++ n’autorisent les fonctions nestedes, mais C GNU le permet en tant qu’extension. Voici un bon article de Wikipédia sur le sujet.

Clang / Apple travaillent sur des «blocs», des fonctions anonymes en C! :-RÉ

^ (vide) {printf (“hello world \ n”); }

info ici et spec ici , et ars technica en a un peu

Non, et il y a au moins une raison pour laquelle autoriser les choses compliquerait les choses. Les fonctions nestedes sont généralement censées avoir access à la scope englobante. Cela fait en sorte que la “stack” ne puisse plus être représentée avec une structure de données de stack. Au lieu de cela, un arbre complet est nécessaire.

Considérez le code suivant qui comstack réellement dans gcc comme le suggère KennyTM.

 #include  typedef double (*retdouble)(); retdouble wrapper(double a) { double square() { return a * a; } return square; } int use_stack_frame(double b) { return (int)b; } int main(int argc, char** argv) { retdouble square = wrapper(3); printf("expect 9 actual %f\n", square()); printf("expect 3 actual %d\n", use_stack_frame(3)); printf("expect 16 actual %f\n", wrapper(4)()); printf("expect 9 actual %f\n", square()); return 0; } 

J’ai placé ce que la plupart des gens s’attendent à être imprimé, mais en fait, cela est imprimé:

 expect 9 actual 9.000000 expect 3 actual 3 expect 16 actual 16.000000 expect 9 actual 16.000000 

Notez que la dernière ligne appelle la fonction “square”, mais que la valeur “a” à laquelle elle accède a été modifiée lors de l’appel de wrapper (4). En effet, un cadre “stack” séparé n’est pas créé pour chaque invocation de “wrapper”.

Notez que ces types de fonctions nestedes sont en fait assez courants dans les autres langages qui les prennent en charge, comme lisp et python (et même les versions récentes de Matlab). Elles conduisent à des capacités de functional programmings très puissantes, mais elles excluent l’utilisation d’une stack pour contenir des trames de scope locales.

 void foo() { class local_to_foo { public: static void another_foo() { printf("whatevs"); } }; local_to_foo::another_foo(); } 

Ou Lambda en C ++ 0x.

Vous pouvez imbriquer une classe locale dans une fonction. Dans ce cas, la classe ne sera accessible qu’à cette fonction. Vous pouvez ensuite écrire votre fonction nestede en tant que membre de la classe locale:

 #include  int f() { class G { public: int operator()() { return 1; } } g; return g(); } int main() { std::cout << f() << std::endl; } 

Gardez toutefois à l'esprit que vous ne pouvez pas transmettre une fonction définie dans une classe locale à un algorithme STL, tel que sort() .

 int f() { class G { public: bool operator()(int i, int j) { return false; } } g; std::vector v; std::sort(v.begin(), v.end(), g); // Fails to comstack } 

L'erreur que vous obtiendrez de gcc est "test.cpp: 18: erreur: pas de fonction correspondante pour l'appel à` sort (__ gnu_cxx :: __ normal_iterator>>, __gnu_cxx :: __ normal_iterator>>, f () :: G &) ""

Il n’est pas possible de déclarer une fonction dans une fonction. Vous pouvez cependant déclarer une fonction dans un espace de noms ou dans une classe en C ++.

Pas en C standard, mais gcc et clang supportent comme une extension. Voir le manuel en ligne de gcc .

Bien que C et C ++ interdisent les fonctions nestedes, quelques compilateurs les supportent quand même (par exemple, si la mémoire est utilisée, gcc peut, au moins avec les bons indicateurs). Un foncteur nested est cependant beaucoup plus portable.

Aucune fonction nestede en C / C ++, malheureusement.

Comme d’autres réponses l’ont mentionné, les standards C et C ++ ne vous permettent pas de définir des fonctions nestedes. (Certains compilateurs le permettent peut-être comme une extension, mais je ne peux pas dire que je l’ai vu utilisé).

Vous pouvez déclarer une autre fonction dans une fonction afin de pouvoir l’appeler, mais la définition de cette fonction doit exister en dehors de la fonction actuelle:

 #include  #include  int main( int argc, char* argv[]) { int foo(int x); /* int bar(int x) { // this can't be done return x; } */ int a = 3; printf( "%d\n", foo(a)); return 0; } int foo( int x) { return x+1; } 

Une déclaration de fonction sans “spécificateur de liaison” explicite a une liaison extern . Ainsi, alors que la déclaration du nom foo dans la fonction main() est définie sur main() , elle sera liée à la fonction foo() définie plus tard dans le fichier (ou dans un autre fichier si c’est là que foo() est défini ).