¿Por qué estás tratando de hacer esto? Explicar su propósito podría permitir que alguien le diga la forma correcta de lograr su objetivo.
Thomas Owens
3
gcc admite funciones anidadas como una extensión no estándar. Pero mejor no lo use incluso si está usando gcc. Y en modo C ++, no está disponible de todos modos.
Sven Marnach
27
@Thomas: ¿Porque sería bueno reducir el alcance de a? Las funciones en funciones es una característica habitual en otros idiomas.
Johan Kotlinski
64
Él está hablando de funciones anidadas. De manera similar a ser capaz de las siguientes clases dentro de las clases, quiere anidar una función dentro de una función. En realidad, he tenido situaciones en las que también lo habría hecho, si fuera posible. Hay lenguajes (por ejemplo, F #) que permiten esto, y puedo decirle que puede hacer que el código sea mucho más claro, legible y mantenible sin contaminar una biblioteca con docenas de funciones auxiliares que son inútiles fuera de un contexto muy específico. ;)
Mephane
16
@Thomas - funciones anidadas pueden ser un excelente mecanismo para romper las funciones complejas / algoritmos sin sin llenar el alcance actual con funciones que son no de uso general en el ámbito de encerramiento. Pascal y Ada tienen un apoyo encantador (IMO) para ellos. Lo mismo con Scala y muchos otros idiomas respetados antiguos / nuevos. Como cualquier otra característica, también se puede abusar de ellos, pero esa es una función del desarrollador. En mi opinión, han sido mucho más beneficiosos que perjudiciales.
luis.espinal
Respuestas:
271
Modern C ++ - ¡Sí, con lambdas!
En las versiones actuales de c ++ (C ++ 11, C ++ 14 y C ++ 17), puede tener funciones dentro de funciones en forma de lambda:
int main(){// This declares a lambda, which can be called just like a functionauto print_message =[](std::string message){
std::cout << message <<"\n";};// Prints "Hello!" 10 timesfor(int i =0; i <10; i++){
print_message("Hello!");}}
Lambdas también puede modificar variables locales a través de ** captura por referencia *. Con la captura por referencia, el lambda tiene acceso a todas las variables locales declaradas en el alcance del lambda. Puede modificarlos y cambiarlos normalmente.
int main(){int i =0;// Captures i by reference; increments it by oneauto addOne =[&](){
i++;};while(i <10){
addOne();//Add 1 to i
std::cout << i <<"\n";}}
C ++ 98 y C ++ 03: no directamente, pero sí con funciones estáticas dentro de las clases locales
C ++ no es compatible con eso directamente.
Dicho esto, puede tener clases locales, y pueden tener funciones (no statico static), por lo que puede obtener esto hasta cierto punto, aunque es un poco un error:
int main()// it's int, dammit!{struct X {// struct's as good as classstaticvoid a(){}};
X::a();return0;}
Sin embargo, cuestionaría la praxis. Todo el mundo sabe (bueno, ahora que lo hace, de todos modos :)) C ++ no admite funciones locales, por lo que están acostumbrados a no tenerlas. Sin embargo, no están acostumbrados a ese error. Pasaría bastante tiempo en este código para asegurarme de que realmente solo esté allí para permitir funciones locales. No está bien.
Main también toma dos argumentos si va a ser pedante sobre el tipo de retorno. :) (¿O es eso opcional pero no el regreso en estos días? No puedo seguir el ritmo.)
Leo Davidson
3
Esto es simplemente malo: rompe todas las convenciones de código bueno y limpio. No puedo pensar en una sola instancia donde esta sea una buena idea.
Thomas Owens
19
@Thomas Owens: es bueno si necesita una función de devolución de llamada y no desea contaminar algún otro espacio de nombres con ella.
Leo Davidson
99
@Leo: El estándar dice que hay dos formas permitidas para main: int main()yint main(int argc, char* argv[])
John Dibling el
8
El estándar dice int main()y int main(int argc, char* argv[])debe ser compatible y otros pueden ser compatibles, pero todos tienen return int.
JoeG
260
Para todos los efectos, C ++ admite esto a través de lambdas : 1
int main(){auto f =[](){return42;};
std::cout <<"f() = "<< f()<< std::endl;}
Aquí, fhay un objeto lambda que actúa como una función local en main. Se pueden especificar capturas para permitir que la función acceda a objetos locales.
Detrás de escena, fhay un objeto de función (es decir, un objeto de un tipo que proporciona un operator()). El compilador crea el tipo de objeto de función en función de la lambda.
Ah, eso es genial! No lo pensé. Esto es mucho mejor que mi idea, +1de mi parte.
sbi
1
@sbi: en realidad he usado estructuras locales para simular esto en el pasado (sí, estoy avergonzado de mí mismo). Pero la utilidad está limitada por el hecho de que las estructuras locales no crean un cierre, es decir, no puede acceder a las variables locales en ellas. Debe pasar y almacenarlos explícitamente a través de un constructor.
Konrad Rudolph
1
@ Konrad: Otro problema con ellos es que en C ++ 98 no debe usar tipos locales como parámetros de plantilla. Sin embargo, creo que C ++ 1x ha eliminado esa restricción. (¿O fue C ++ 03?)
sbi
3
@luis: Debo estar de acuerdo con Fred. Está adjuntando un significado a lambdas que simplemente no tienen (ni en C ++ ni en otros lenguajes con los que he trabajado, que no incluyen Python y Ada, para el registro). Además, hacer esa distinción simplemente no tiene sentido en C ++ porque C ++ no tiene funciones locales, punto. Solo tiene lambdas. Si desea limitar el alcance de una función similar a una función, sus únicas opciones son lambdas o la estructura local mencionada en otras respuestas. Yo diría que este último es demasiado complicado para ser de algún interés práctico.
Konrad Rudolph el
2
@AustinWBryan No, las lambdas en C ++ son solo azúcar sintáctica para los functors y tienen cero gastos generales. Hay una pregunta con más detalles en alguna parte de este sitio web.
Konrad Rudolph
42
Ya se han mencionado las clases locales, pero aquí hay una manera de permitir que aparezcan aún más como funciones locales, utilizando una sobrecarga de operador () y una clase anónima:
int main(){struct{unsignedintoperator()(unsignedint val)const{return val<=1?1: val*(*this)(val-1);}} fac;
std::cout << fac(5)<<'\n';}
No aconsejo usar esto, es solo un truco divertido (puede hacer, pero no debería).
Actualización 2014:
Con el surgimiento de C ++ 11 hace un tiempo, ahora puede tener funciones locales cuya sintaxis recuerda un poco a JavaScript:
Debería ser operator () (unsigned int val), te falta un paréntesis.
Joe D
1
En realidad, esto es algo perfectamente razonable si necesita pasar este functor a una función o algoritmo stl, como std::sort(), o std::for_each().
Dima
1
@Dima: Desafortunadamente, en C ++ 03, los tipos definidos localmente no pueden usarse como argumentos de plantilla. C ++ 0x corrige esto, pero también proporciona las soluciones mucho más agradables de lambdas, por lo que aún no lo haría.
Ben Voigt
Vaya, tienes razón. Culpa mía. Pero aún así, esto no es solo un truco divertido. Hubiera sido útil si se permitiera. :)
Dima
3
La recursión es compatible. Sin embargo, no puede usar autopara declarar la variable. Stroustrup da el ejemplo: function<void(char*b, char*e)> rev=[](char*b, char*e) { if( 1<e-b ) { swap( *b, *--e); rev(++b,e); } };para invertir una cadena dada punteros de inicio y fin.
Epónimo
17
No.
¿Que estás tratando de hacer?
solución alterna:
int main(void){struct foo
{voidoperator()(){int a =1;}};
foo b;
b();// call the operator()}
No estoy seguro de que pueda, excepto creando un objeto en su lugar (que agrega tanto ruido, IMO). A menos que haya algo inteligente que pueda hacer con los espacios de nombres, pero no puedo pensar en eso y probablemente no sea una buena idea abusar del lenguaje más de lo que ya somos. :)
Leo Davidson
El método para deshacerse de dummy :: está en una de las otras respuestas.
Sebastian Mach
8
Como otros han mencionado, puede usar funciones anidadas usando las extensiones de lenguaje gnu en gcc. Si usted (o su proyecto) se adhiere a la cadena de herramientas gcc, su código será principalmente portátil en las diferentes arquitecturas a las que apunta el compilador gcc.
Sin embargo, si existe un posible requisito de que necesite compilar código con una cadena de herramientas diferente, entonces me mantendría alejado de tales extensiones.
También pisaría con cuidado al usar funciones anidadas. Son una solución hermosa para administrar la estructura de bloques de código complejos, pero cohesivos (cuyas piezas no están destinadas para uso externo / general). También son muy útiles para controlar la contaminación del espacio de nombres (una preocupación muy real con los complejos naturalmente / clases largas en idiomas detallados).
Pero como cualquier cosa, pueden estar abiertos al abuso.
Es triste que C / C ++ no sea compatible con características como un estándar. La mayoría de las variantes pascales y Ada sí (casi todos los lenguajes basados en Algol sí). Lo mismo con JavaScript. Lo mismo con los idiomas modernos como Scala. Lo mismo con lenguajes venerables como Erlang, Lisp o Python.
Y al igual que con C / C ++, desafortunadamente, Java (con el que gano la mayor parte de mi vida) no lo hace.
Menciono Java aquí porque veo varios carteles que sugieren el uso de clases y métodos de clase como alternativas a las funciones anidadas. Y esa también es la solución típica en Java.
Respuesta corta: no.
Hacerlo tiende a introducir una complejidad artificial innecesaria en una jerarquía de clases. En igualdad de condiciones, lo ideal es tener una jerarquía de clases (y sus espacios de nombres y ámbitos que abarquen) que represente un dominio real lo más simple posible.
Las funciones anidadas ayudan a lidiar con la complejidad "privada" dentro de la función. Al carecer de esas facilidades, uno debería tratar de evitar propagar esa complejidad "privada" dentro del modelo de clase.
En software (y en cualquier disciplina de ingeniería), el modelado es una cuestión de compensaciones. Por lo tanto, en la vida real, habrá excepciones justificadas a esas reglas (o más bien pautas). Proceda con cuidado, sin embargo.
No puede tener funciones locales en C ++. Sin embargo, C ++ 11 tiene lambdas . Las lambdas son básicamente variables que funcionan como funciones.
Una lambda tiene el tipo std::function(en realidad eso no es del todo cierto , pero en la mayoría de los casos se puede suponer que sí). Para usar este tipo, debe hacerlo #include <functional>. std::functiones una plantilla, tomando como argumento de plantilla el tipo de retorno y los tipos de argumento, con la sintaxis std::function<ReturnType(ArgumentTypes). Por ejemplo, std::function<int(std::string, float)>es una lambda que devuelve un inty toma dos argumentos, uno std::stringy uno float. El más común es std::function<void()>, que no devuelve nada y no toma argumentos.
Una vez que se declara una lambda, se llama como una función normal, utilizando la sintaxis lambda(arguments).
Para definir una lambda, use la sintaxis [captures](arguments){code}(hay otras formas de hacerlo, pero no las mencionaré aquí). argumentses qué argumentos toma el lambda y codees el código que debe ejecutarse cuando se llama al lambda. Usualmente pones [=]o [&]como capturas. [=]significa que captura todas las variables en el ámbito en el que el valor se define por valor, lo que significa que mantendrán el valor que tenían cuando se declaró la lambda. [&]significa que captura todas las variables en el alcance por referencia, lo que significa que siempre tendrán su valor actual, pero si se borran de la memoria, el programa se bloqueará. Aquí hay unos ejemplos:
#include<functional>#include<iostream>int main(){int x =1;
std::function<void()> lambda1 =[=](){
std::cout << x << std::endl;};
std::function<void()> lambda2 =[&](){
std::cout << x << std::endl;};
x =2;
lambda1();//Prints 1 since that was the value of x when it was captured and x was captured by value with [=]
lambda2();//Prints 2 since that's the current value of x and x was captured by value with [&]
std::function<void()> lambda3 =[](){}, lambda4 =[](){};//I prefer to initialize these since calling an uninitialized lambda is undefined behavior.//[](){} is the empty lambda.{int y =3;//y will be deleted from the memory at the end of this scope
lambda3 =[=](){
std::cout << y << endl;};
lambda4 =[&](){
std::cout << y << endl;};}
lambda3();//Prints 3, since that's the value y had when it was captured
lambda4();//Causes the program to crash, since y was captured by reference and y doesn't exist anymore.//This is a bit like if you had a pointer to y which now points nowhere because y has been deleted from the memory.//This is why you should be careful when capturing by reference.return0;}
También puede capturar variables específicas especificando sus nombres. Simplemente especificando su nombre los capturará por valor, especificando su nombre con un &antes los capturará por referencia. Por ejemplo, [=, &foo]capturará todas las variables por valor, excepto las fooque se capturarán por referencia, y [&, foo]capturará todas las variables por referencia, excepto las fooque se capturarán por valor. También puede capturar solo variables específicas, por ejemplo [&foo], capturará foopor referencia y no capturará otras variables. También puede capturar ninguna variable utilizando []. Si intenta utilizar una variable en una lambda que no capturó, no se compilará. Aquí hay un ejemplo:
#include<functional>int main(){int x =4, y =5;
std::function<void(int)> myLambda =[y](int z){int xSquare = x * x;//Compiler error because x wasn't capturedint ySquare = y * y;//OK because y was capturedint zSquare = z * z;//OK because z is an argument of the lambda};return0;}
No puede cambiar el valor de una variable que fue capturada por valor dentro de una lambda (las variables capturadas por valor tienen un consttipo dentro de la lambda). Para hacerlo, debe capturar la variable por referencia. Aquí hay un ejemplo:
#include<functional>int main(){int x =3, y =5;
std::function<void()> myLambda =[x,&y](){
x =2;//Compiler error because x is captured by value and so it's of type const int inside the lambda
y =2;//OK because y is captured by reference};
x =2;//This is of course OK because we're not inside the lambdareturn0;}
Además, llamar a lambdas no inicializadas es un comportamiento indefinido y generalmente hará que el programa se bloquee. Por ejemplo, nunca hagas esto:
std::function<void()> lambda;
lambda();//Undefined behavior because lambda is uninitialized
Ejemplos
Aquí está el código de lo que quería hacer en su pregunta usando lambdas:
#include<functional>//Don't forget this, otherwise you won't be able to use the std::function typeint main(){
std::function<void()> a =[](){// code}
a();return0;}
Aquí hay un ejemplo más avanzado de una lambda:
#include<functional>//For std::function#include<iostream>//For std::coutint main(){int x =4;
std::function<float(int)> divideByX =[x](int y){return(float)y /(float)x;//x is a captured variable, y is an argument}
std::cout << divideByX(3)<< std::endl;//Prints 0.75return0;}
No, no está permitido. Ni C ni C ++ admiten esta característica de manera predeterminada, sin embargo, TonyK señala (en los comentarios) que hay extensiones para el compilador C de GNU que permiten este comportamiento en C.
Es compatible con el compilador GNU C, como una extensión especial. Pero solo para C, no para C ++.
TonyK
Ah No tengo extensiones especiales en mi compilador de C. Sin embargo, es bueno saberlo. Agregaré ese titbit a mi respuesta.
Thomas Owens
He usado la extensión gcc para admitir funciones anidadas (en C, sin embargo, no en C ++). Las funciones anidadas son algo ingenioso (como en Pascal y Ada) para administrar estructuras complejas pero cohesivas que no están destinadas a ser de uso general. Siempre que se use la cadena de herramientas gcc, se garantiza que sea principalmente portátil para todas las arquitecturas específicas. Pero si hay un cambio de tener que compilar el código resultante con un compilador que no sea gcc, entonces, es mejor evitar tales extensiones y pegarse lo más cerca posible del mantra ansi / posix.
luis.espinal 01 de
7
Todos estos trucos se ven (más o menos) como funciones locales, pero no funcionan así. En una función local puede usar variables locales de sus súper funciones. Es una especie de semi-globals. Ninguno de estos trucos puede hacer eso. El más cercano es el truco lambda de c ++ 0x, pero su cierre está sujeto al tiempo de definición, no al tiempo de uso.
Ahora creo que esta es la mejor respuesta. Aunque es posible declarar una función dentro de una función (que uso todo el tiempo), no es una función local como se define en muchos otros idiomas. Todavía es bueno saber de la posibilidad.
Alexis Wilke
6
No puede definir una función libre dentro de otra en C ++.
Alexis, tienes razón al decir que no está perfectamente limpio. Todavía está cerca de estar limpio, ya que expresa bien lo que el programador pretendía hacer, sin efectos secundarios. Considero que el arte de la programación es escribir una expresión humanamente legible que se lea como una novela.
Barney
2
Pero podemos declarar una función dentro de main ():
int main(){void a();}
Aunque la sintaxis es correcta, a veces puede conducir al "análisis más irritante":
#include<iostream>struct U
{
U(): val(0){}
U(int val): val(val){}int val;};struct V
{
V(U a, U b){
std::cout <<"V("<< a.val <<", "<< b.val <<");\n";}~V(){
std::cout <<"~V();\n";}};int main(){int five =5;
V v(U(five), U());}
=> sin salida del programa.
(Solo advertencia de Clang después de la compilación).
Respuestas:
Modern C ++ - ¡Sí, con lambdas!
En las versiones actuales de c ++ (C ++ 11, C ++ 14 y C ++ 17), puede tener funciones dentro de funciones en forma de lambda:
Lambdas también puede modificar variables locales a través de ** captura por referencia *. Con la captura por referencia, el lambda tiene acceso a todas las variables locales declaradas en el alcance del lambda. Puede modificarlos y cambiarlos normalmente.
C ++ 98 y C ++ 03: no directamente, pero sí con funciones estáticas dentro de las clases locales
C ++ no es compatible con eso directamente.
Dicho esto, puede tener clases locales, y pueden tener funciones (no
static
ostatic
), por lo que puede obtener esto hasta cierto punto, aunque es un poco un error:Sin embargo, cuestionaría la praxis. Todo el mundo sabe (bueno, ahora que lo hace, de todos modos
:)
) C ++ no admite funciones locales, por lo que están acostumbrados a no tenerlas. Sin embargo, no están acostumbrados a ese error. Pasaría bastante tiempo en este código para asegurarme de que realmente solo esté allí para permitir funciones locales. No está bien.fuente
int main()
yint main(int argc, char* argv[])
int main()
yint main(int argc, char* argv[])
debe ser compatible y otros pueden ser compatibles, pero todos tienen return int.Para todos los efectos, C ++ admite esto a través de lambdas : 1
Aquí,
f
hay un objeto lambda que actúa como una función local enmain
. Se pueden especificar capturas para permitir que la función acceda a objetos locales.Detrás de escena,
f
hay un objeto de función (es decir, un objeto de un tipo que proporciona unoperator()
). El compilador crea el tipo de objeto de función en función de la lambda.1 desde C ++ 11
fuente
+1
de mi parte.Ya se han mencionado las clases locales, pero aquí hay una manera de permitir que aparezcan aún más como funciones locales, utilizando una sobrecarga de operador () y una clase anónima:
No aconsejo usar esto, es solo un truco divertido (puede hacer, pero no debería).
Actualización 2014:
Con el surgimiento de C ++ 11 hace un tiempo, ahora puede tener funciones locales cuya sintaxis recuerda un poco a JavaScript:
fuente
operator () (unsigned int val)
, te falta un paréntesis.std::sort()
, ostd::for_each()
.auto
para declarar la variable. Stroustrup da el ejemplo:function<void(char*b, char*e)> rev=[](char*b, char*e) { if( 1<e-b ) { swap( *b, *--e); rev(++b,e); } };
para invertir una cadena dada punteros de inicio y fin.No.
¿Que estás tratando de hacer?
solución alterna:
fuente
Comenzando con C ++ 11, puede usar lambdas adecuadas . Vea las otras respuestas para más detalles.
Respuesta anterior: Puedes, más o menos, pero tienes que hacer trampa y usar una clase ficticia:
fuente
Como otros han mencionado, puede usar funciones anidadas usando las extensiones de lenguaje gnu en gcc. Si usted (o su proyecto) se adhiere a la cadena de herramientas gcc, su código será principalmente portátil en las diferentes arquitecturas a las que apunta el compilador gcc.
Sin embargo, si existe un posible requisito de que necesite compilar código con una cadena de herramientas diferente, entonces me mantendría alejado de tales extensiones.
También pisaría con cuidado al usar funciones anidadas. Son una solución hermosa para administrar la estructura de bloques de código complejos, pero cohesivos (cuyas piezas no están destinadas para uso externo / general). También son muy útiles para controlar la contaminación del espacio de nombres (una preocupación muy real con los complejos naturalmente / clases largas en idiomas detallados).
Pero como cualquier cosa, pueden estar abiertos al abuso.
Es triste que C / C ++ no sea compatible con características como un estándar. La mayoría de las variantes pascales y Ada sí (casi todos los lenguajes basados en Algol sí). Lo mismo con JavaScript. Lo mismo con los idiomas modernos como Scala. Lo mismo con lenguajes venerables como Erlang, Lisp o Python.
Y al igual que con C / C ++, desafortunadamente, Java (con el que gano la mayor parte de mi vida) no lo hace.
Menciono Java aquí porque veo varios carteles que sugieren el uso de clases y métodos de clase como alternativas a las funciones anidadas. Y esa también es la solución típica en Java.
Respuesta corta: no.
Hacerlo tiende a introducir una complejidad artificial innecesaria en una jerarquía de clases. En igualdad de condiciones, lo ideal es tener una jerarquía de clases (y sus espacios de nombres y ámbitos que abarquen) que represente un dominio real lo más simple posible.
Las funciones anidadas ayudan a lidiar con la complejidad "privada" dentro de la función. Al carecer de esas facilidades, uno debería tratar de evitar propagar esa complejidad "privada" dentro del modelo de clase.
En software (y en cualquier disciplina de ingeniería), el modelado es una cuestión de compensaciones. Por lo tanto, en la vida real, habrá excepciones justificadas a esas reglas (o más bien pautas). Proceda con cuidado, sin embargo.
fuente
No puede tener funciones locales en C ++. Sin embargo, C ++ 11 tiene lambdas . Las lambdas son básicamente variables que funcionan como funciones.
Una lambda tiene el tipo
std::function
(en realidad eso no es del todo cierto , pero en la mayoría de los casos se puede suponer que sí). Para usar este tipo, debe hacerlo#include <functional>
.std::function
es una plantilla, tomando como argumento de plantilla el tipo de retorno y los tipos de argumento, con la sintaxisstd::function<ReturnType(ArgumentTypes)
. Por ejemplo,std::function<int(std::string, float)>
es una lambda que devuelve unint
y toma dos argumentos, unostd::string
y unofloat
. El más común esstd::function<void()>
, que no devuelve nada y no toma argumentos.Una vez que se declara una lambda, se llama como una función normal, utilizando la sintaxis
lambda(arguments)
.Para definir una lambda, use la sintaxis
[captures](arguments){code}
(hay otras formas de hacerlo, pero no las mencionaré aquí).arguments
es qué argumentos toma el lambda ycode
es el código que debe ejecutarse cuando se llama al lambda. Usualmente pones[=]
o[&]
como capturas.[=]
significa que captura todas las variables en el ámbito en el que el valor se define por valor, lo que significa que mantendrán el valor que tenían cuando se declaró la lambda.[&]
significa que captura todas las variables en el alcance por referencia, lo que significa que siempre tendrán su valor actual, pero si se borran de la memoria, el programa se bloqueará. Aquí hay unos ejemplos:También puede capturar variables específicas especificando sus nombres. Simplemente especificando su nombre los capturará por valor, especificando su nombre con un
&
antes los capturará por referencia. Por ejemplo,[=, &foo]
capturará todas las variables por valor, excepto lasfoo
que se capturarán por referencia, y[&, foo]
capturará todas las variables por referencia, excepto lasfoo
que se capturarán por valor. También puede capturar solo variables específicas, por ejemplo[&foo]
, capturaráfoo
por referencia y no capturará otras variables. También puede capturar ninguna variable utilizando[]
. Si intenta utilizar una variable en una lambda que no capturó, no se compilará. Aquí hay un ejemplo:No puede cambiar el valor de una variable que fue capturada por valor dentro de una lambda (las variables capturadas por valor tienen un
const
tipo dentro de la lambda). Para hacerlo, debe capturar la variable por referencia. Aquí hay un ejemplo:Además, llamar a lambdas no inicializadas es un comportamiento indefinido y generalmente hará que el programa se bloquee. Por ejemplo, nunca hagas esto:
Ejemplos
Aquí está el código de lo que quería hacer en su pregunta usando lambdas:
Aquí hay un ejemplo más avanzado de una lambda:
fuente
No, no está permitido. Ni C ni C ++ admiten esta característica de manera predeterminada, sin embargo, TonyK señala (en los comentarios) que hay extensiones para el compilador C de GNU que permiten este comportamiento en C.
fuente
Todos estos trucos se ven (más o menos) como funciones locales, pero no funcionan así. En una función local puede usar variables locales de sus súper funciones. Es una especie de semi-globals. Ninguno de estos trucos puede hacer eso. El más cercano es el truco lambda de c ++ 0x, pero su cierre está sujeto al tiempo de definición, no al tiempo de uso.
fuente
No puede definir una función libre dentro de otra en C ++.
fuente
Permítanme publicar aquí una solución para C ++ 03 que considero lo más limpia posible. *
(*) en el mundo C ++ el uso de macros nunca se considera limpio.
fuente
Pero podemos declarar una función dentro de main ():
Aunque la sintaxis es correcta, a veces puede conducir al "análisis más irritante":
=> sin salida del programa.
(Solo advertencia de Clang después de la compilación).
El análisis más irritante de C ++ nuevamente
fuente