Donde en el estándar son funciones que devuelven funciones no permitidas? Entiendo que son conceptualmente ridículo, pero a mí me parece que la gramática permitiría a ellos. De acuerdo a la presente página web, un «noptr-declarador [es] cualquier válido declarador«, que incluiría la sentencia declarativa de una función:

int f()();

Acerca de la sintaxis.

A mí me parece que la sintaxis, como se señala en [dcl.decl], permite

int f(char)(double)

cual podría ser interpretado como la función f que toma un char y devuelve una función con la misma firma que int g(double).

1    declarator:
2       ptr-declarator
3       noptr-declarator parameters-and-qualifiers trailing-return-type
4    ptr-declarator:
5        noptr-declarator
6        ptr-operator ptr-declarator
7    noptr-declarator:
8        declarator-id attribute-specifier-seq opt
9        noptr-declarator parameters-and-qualifiers
10       noptr-declarator [ constant-expression opt ] attribute-specifier-seq opt
11       ( ptr-declarator )
12    parameters-and-qualifiers:
13       ( parameter-declaration-clause ) cv-qualifier-seqAfter

A grandes rasgos, después de
1->2, 2=4, 4->6, 4->6
usted debe tener
ptr-el operador ptr-el operador ptr-operador
A continuación, utilice 4->5, 5=7, 7->8 para la primera sentencia declarativa; 4->5, 5=7, 7->9 para el segundo y tercer declarators.

  • C camino de retorno void * y lo echó a la función 🙂 C++ camino de retorno de referencia o puntero a objeto que tiene cierta función (modelo de estrategia)
  • Eso es verdaderamente terrible consejo. Incluso en C se puede devolver un puntero a función. En C++ se puede usar std::función o cualquier objeto invocable.
  • Linux’ signal función es un típico ejemplo de una función que devuelve otra función (puntero), y no creo que esto es ridiculus. La única cosa ridiculus es la sintaxis: void (*signal(int signo, void (*func )(int)))(int);
  • Que no devuelve una función. Devuelve un puntero a función.
  • Bien, ahora estás haciendo el mismo error que Anzurio. El OP no decir que el retorno de los punteros a función es ridículo. En todos los.
  • Maldita sea. Lea la pregunta, como si el OP quiere volver punteros de función y no de funciones reales.
  • Estás equivocado en pensar que C++ es principalmente definido por una gramática. La gramática no significa mucho (y es conocida por ser extremadamente ambigua para C++; esta es la razón por la codificación en C++ de los analizadores es aburrido es difícil, y lo es la lectura de código de C++!)
  • Finalmente votada abajo a la pregunta, porque es la mezcla de la gramática y el lenguaje de definición de lo que para C++ en particular (y, por desgracia, en mi humilde opinión) es muy diferente. Esta es la razón por la que C++ es tan difícil de leer, difícil de aprender, difícil de analizar (todo esto porque en el legado y hacia atrás look&feel compatibilidad con C razones)
  • la gramática y el lenguaje de definición se han mezclado, no agitado. Así que, ¿por qué la mezcla de malo?
  • Usted menciona que la gramática les permitiría, y tienes razón; no es la gramática la que prohibe eso. Pero he entendido su pregunta como pidiendo algo de la sintaxis de la regla de prohibirla (y no hay ninguno, ya que se trata de una cuestión semántica)
  • La pregunta es «¿Dónde en el estándar son funciones que devuelven las funciones rechazado?» No es calificado por pedir una sintaxis específica de la regla.
  • la siguiente sentencia en la cuestión está terminando «a mí me parece que la gramática les permitiría», por lo que puede ser entendido (al menos por parte de los no-hablante nativo de inglés que soy yo) como por qué la gramática es prohibir que…
  • No hay nada conceptualmente ridículo acerca de las funciones de devolución de funciones. Se hace todo el tiempo en otros idiomas. está hecho en C++ en la forma de las funciones de devolución de los cierres.
  • Posibles duplicados de Función que devuelve una expresión lambda

InformationsquelleAutor Hector | 2015-07-13

5 Comentarios

  1. 54

    De [dcl.fct], bastante explícita:

    Funciones no tendrá un retorno de tipo de tipo de matriz o función, a pesar de que puede tener un tipo de retorno de
    tipo de puntero o una referencia a tales cosas. No habrá matrices de funciones, aunque no pueden ser matrices
    de punteros a funciones.

    Con C++11, usted probablemente sólo quiere:

    std::function<int()> f();
    std::function<int(double)> f(char);

    Hay cierta confusión con respecto a la de C++ de la gramática. La declaración de int f(char)(double); puede ser analizada de acuerdo a la gramática. Aquí es un árbol de análisis:

    C++ la función devuelve la función

    Además un parse es aún significativo, basado en [dcl.fct]/1:

    En una declaración T D donde D tiene la forma

        D1 ( parámetro-declaración-cláusula ) cv-qualifier-seqopción

            ref-calificadoropción excepción de la especificaciónopción atributo-especificador-seqopción

    y el tipo de contenidos declarador-id en la declaración T D1 es «derivados-declaradores-tipo-lista de T«, el
    tipo de la declarador-id en D es «derivados-declaradores-tipo-lista de función de (parámetro-declaración-cláusula ) cv-qualifier-seqopción
    ref-calificadoropción volver T«.

    En este ejemplo T == int, D == f(char)(double), D1 == f(char). El tipo de la declarador-id en T D1 (int f(char)) es «la función de (char) devuelve int». Así derivados-declaradores-tipo-lista de es «la función de (char) volver». Por lo tanto, el tipo de f se puede leer como «función de (char) devuelve la función de la (doble) devuelve int.»

    Es en última instancia mucho ado sobre nada, ya que este es un explícitamente rechazado declarador de forma. Pero no por la gramática.

    • Aviso que no es un la gramática cosa. El C++ de la gramática (en cuasi notación EBNF) probablemente permite la devolución de funciones. La semántica de la prohibió.
    • La norma es de más de 1000 páginas. Es fácil pasar por alto cosas. En este caso, que es el párrafo 10 … demasiado hacia abajo …
    • Es por eso que hemos Pdf con marcadores. Saltar a la Funciones de la sección (8.3.5), a continuación de la búsqueda para «volver»
    • no hay necesidad de ser condescendiente. Hice una búsqueda en 8.4, a continuación, las dos primeras páginas de 8.3.5. En ese momento, pensé que yo no entiendo algo.
    • Yo no estaba tratando de ser condescendiente. Pensé que estaba leyendo la versión en papel y fue lo que sugiere una alternativa más conveniente.
    • looooooool para el árbol de análisis 🙂
    • Es hermoso ¿no
    • Quiero un beso de la muerte
    • Y entonces me acordé de graphviz…
    • wheeeeeeeeeeeeeeeeee
    • Hay un chiste que me falta para el nuevo nombre?
    • Jaja hola. No, no realmente, sólo un tonto injoke de La Pizarra, relativa a un particular divertido al azar tweet. Puede ser BarryTheNonHatchet
    • Lol, ok. Difícil seguir la pista de estos días con todos los cambios de nombre 🙂
    • Como un ninja… por lo que vale es sólo mi segundo cambio de nombre en tres (?) años
    • no funciona para stdcall.

  2. 7

    Con C++11 (pero no en versiones anteriores de C++) no sólo se puede devolver C-como punteros a función, sino también el C++ cierres, en particular con funciones anónimas. Véase también std::función

    La norma no permite (semánticamente, no sintácticamente – así es no una cuestión de gramática ; ver Barry respuesta para la citación) regresar funciones (y también no permitir sizeof en funciones!) pero permite volver punteros a función.

    por CIERTO, no creo que pudiera volver a toda funciones. Qué significaría eso? ¿Cómo implementar eso? Prácticamente hablando, una función es una parte de código de bloque, y su nombre es (como para las matrices) un puntero al inicio de la función del código de la máquina.

    Un buen truco puede ser la construcción (a través de mecanismos que fuera del estándar de C++) de una función en tiempo de ejecución (y, a continuación, el manejo de su función de puntero). Algunas bibliotecas externas podría permitir que: usted podría utilizar un JIT de la biblioteca (por ejemplo,asmjit, gccjit, LLVM …) o simplemente generar código C++, a continuación, compilar y dlopen & dlsym en sistemas POSIX, etc.

    PS. Usted tiene probablemente razón en la comprensión de que el C++11 gramática (las reglas EBNF en la norma) no no permitir el regreso de las funciones. Es un semántica regla declaró en la llanura inglés, el cual no permite que esto se no cualquier regla de gramática). Me refiero a que el EBNF solo permitiría:

     //semantically wrong... but perhaps not syntactically
     typedef int sigfun_T(std::string);
     sigfun_T foobar(int);

    y es por la semántica razones (no porque de reglas EBNF) que un compilador es, con razón, rechazando el código anterior. Prácticamente hablando, la tabla de símbolos importa mucho para el compilador de C++ (y es no sintaxis o gramática independiente del contexto).

    La triste realidad de C++ es que (por motivos heredados) a su gramática (solo) es muy ambiguo. Por lo tanto C++11 es difícil de leer (para los humanos), difícil de escribir (para desarrolladores), difícil de analizar (para compiladores), ….

    • «La norma de no permitir[s] de regresar funciones» no responde a la pregunta «qué parte de la norma de no permitir[s] de regresar funciones».
    • «por CIERTO, no creo que pudiera volver a toda funciones. Qué significaría eso? ¿Cómo implementar eso.» a la Derecha, el OP dijo que en la pregunta. Nadie puede leer hoy 🙁
    • En realidad, con un jit de la biblioteca, se podría volver una función; o, al menos, un bloque de memoria que contiene uno.
    • técnicamente, un JIT biblioteca devuelve un puntero a función y construir un código de función en el espacio de direcciones.
    • se podría escribir un struct func{unsigned char[1024];}; y regresa, entonces usted podría estar regresando a la función entera.
    • Pero que no suelen funcionar. Y pedantically, a continuación, devolver un struct no una función.
    • Acaba de ser el abogado del diablo aquí. Si volvemos una instrucción del procesador (que podría encajar en un registro), podríamos regresar de una función.
    • La mayoría de los procesadores son incapaces de ejecutar una instrucción en un registro. Si mal no recuerdo, IBM/360 tuvo un «Ejecutar» instrucción de la máquina, pero incluso eso se necesita una dirección de memoria….
    • De verdad que no. El tipo de sistema existe!
    • Voy a abogar por el diablo de nuevo. La interpretación de lo que se celebra, en un registro que no es parte de C++. Podría ser una función. Yo estaba frente a los comentarios acerca de JIT bibliotecas de devolución de punteros a funciones en lugar de funciones.
    • La pregunta es acerca de C++. ¿Qué hacer con algunos registros en algunos implementación física no tiene nada que ver con ella. 🙂
    • Imaginar la devolución de un tamaño variable de matriz de bytes que pasa a contener el código máquina. (La variable de tamaño de la matriz de sí mismo; no un puntero a ella). Tenga en cuenta que en C y C++ todas las variables tienen tamaños fijos, de modo que no puede devolver un tamaño variable de objeto, de modo que no puede devolver una función. (Pero usted puede devolver un puntero a uno)
    • Y aunque pudiera, todavía no sería una función. Sería una matriz.
    • el lenguaje permite que usted regrese funciones, que es lo que devuelve una función que haría sería volver a una función. Funciones pasan a ser representado por la longitud variable de las matrices de bytes en todas las máquinas soy consciente de, pero para el idioma propósitos, sería una función, no un array.
    • A la derecha, bueno, eso no es lo que usted dijo hace un momento. 🙂 De nuevo, el tipo de sistema existe y yo, deliberadamente, no lo ignore. Realmente no se agitaba sobre los detalles de implementación como que no es lo que estamos hablando aquí.
    • Se le preguntó lo que significaría el retorno de una función, me respondió. Piense en la diferencia entre devolviendo un puntero a una matriz, y el regreso de la matriz en sí – que es la diferencia entre devolviendo un puntero a una función, y el regreso de la propia función. Hipotéticamente.
    • No me pregunte nada!

  3. 0

    Realidad en C uno no puede pasar o devolver la función. Sólo un puntero/dirección de la función se puede pasar/devuelve, que conceptualmente es bastante cerca. Para ser honesto, gracias a la posibilidad de ommiting & y * con los punteros a función de uno no importa realmente si la función o el puntero se pasa (a menos que contenga cualquier dato estático). Aquí es simple declaración de puntero de función:

    void (*foo)();

    foo es puntero a función que devuelve void y tomar sin argumentos.

    En C++ no es muy diferente. Uno todavía puede usar C-estilo de punteros a función o nuevos útil std::function objeto para todos exigible creaciones. C++ también añade las expresiones lambda que son funciones en línea que trabajan de alguna manera similares a los cierres en los lenguajes funcionales. Permite, no para hacer de todo, pasó funciones globales.

    Y, finalmente, – la devolución de un puntero a función o std::function puede parecer ridículo, pero realmente no lo es. Por ejemplo, el estado de la máquina patrón es (en la mayoría de los casos) se basa en devolver el puntero a la función de manejo de estado siguiente o puede llamar siguiente objeto de estado.

  4. 0

    La gramática formal de C en realidad no permite devolución de funciones, pero, siempre se puede devolver un puntero a función que, para todos los intentos y propósitos, parece que lo que quieres hacer:

      int (*getFunc())(int, int) {  }

    Estoy obsesionado decir, la gramática, es una de las más fundamentales de la explicación de la falta de apoyo de dicha característica. Las reglas son una última preocupación.

    Si la gramática no proporcionan una forma para lograr algo, creo que no importa lo que la semántica o la norma dice que para cualquier contexto dado un lenguaje libre.

    • ¿Cómo encontrar algo útil que es imposible?
    • Me refería a algo como «devolución de funciones por medio de los punteros de función».
    • Bueno, eso no es lo que el OP dijo.
    • «La norma de no permitir[s] de regresar funciones» no responde a la pregunta «qué parte de la norma de no permitir[s] de regresar funciones».
    • Ya que es tan importante para usted (no quiero especular por qué), me estoy quitando esa parte de mi respuesta. Creo que mi respuesta no puede realmente aborda la cuestión; sólo estoy tratando de ser útil y no un auto-justos individuales.
    • No creo que usted entiende LRiO del comentario. Lo OP entiende por «ridículo» fue devolver funciones como un valor. Usted dice que usted encontrará útil no tiene sentido, ya que ni siquiera es legal C o C++ de código. Estás diciendo que regresan de las funciones de puntero/referencia/functor es útil – que es sin duda cierto, pero también una especie de irrelevante para la pregunta.
    • Sí, es terrible que la calidad de los contenidos en este sitio web es importante para mí
    • Que parte con mi opinión personal fue eliminado. No tengo idea de qué más quieres? Desde mi punto de VISTA, la pregunta es errónea, porque no es el estándar de la «culpa». La gramática no permite la devolución de funciones.
    • No es la gramática que no permitir el regreso de las funciones. Es la semántica (y por desgracia, la mayoría de C++11 semántica se describe de manera informal en inglés técnico)
    • ¿te importa que me apunta a la construcción y/o ruta de acceso que le permite? La verdad que me gustaría saber.
    • Sostengo es una gramática problema porque va a ser la pushdown autómata que va a rechazar un programa que «trata» de retorno de una función.
    • He editado mi respuesta a mejorarlo. El codechunk comenzando con typedef int sigfun_T(std::string); es legal C++ la sintaxis de pero no tiene que significa
    • Gracias, en ello! 😀
    • Yo votada abajo, debido a la devolución de una función está prohibido por algo que es no la gramática (pero la «semántica»).
    • He publicado un árbol de análisis para ilustrar que la gramática de este.

  5. 0

    A menos que se devuelve un puntero o una referencia a una función que está bien, la alternativa es la devolución de una copia de una función. Ahora, piense acerca de lo que una copia de una función que parece, actúa como tal, se comporta como tal. Que, lo primero de todo sería una matriz de bytes, que tampoco está permitido, y en segundo lugar de todos los bytes sería la equivalencia de una pieza de código, literalmente, la devolución de una pieza de código….casi todos los heurística de los escáneres de virus podría considerar la posibilidad de que un virus porque también habría ninguna manera de verificar la viabilidad del código devuelto por el sistema de ejecución, o incluso en tiempo de compilación. Incluso si usted podría devolver un array, ¿cómo podría volver a una función? El principal problema con el que devuelve una matriz (lo cual sería una copia en la pila) es que el tamaño no es conocido y no hay ninguna manera de quitar de la pila, y el mismo dilema que existe para las funciones (donde la matriz sería el lenguaje de la máquina código binario). También, si usted hizo de retorno de una función en la que la moda, ¿cómo sería la vuelta y llamar a esa función?

    Para resumir, la idea de devolver una función en lugar de un punto a una función falla, porque la noción de que es un desconocido con el tamaño de la matriz de código de máquina colocado (copiado) en la pila. No es algo que el C o C++ fue diseñado para permitir, y con el código ahora hay manera de dar la vuelta y llamar a esa función, sobre todo yo que quería pasar argumentos.

    Espero que esto tiene sentido

Dejar respuesta

Please enter your comment!
Please enter your name here