structs pointer make how examples example enum ejemplo and c++ function struct prototype

c++ - pointer - Función prototipo de las estructuras



structs and pointers c++ (3)

Hoy me encontré con este pedazo de código:

int main() { struct Foo {}; struct Bar {}; Foo(b)(int (Bar*c)); // ? return 0; }

No tengo absolutamente ninguna idea de lo que está pasando. ¿Mi compilador (VC14) me advierte sobre la función de prototipo no utilizada?

¿Qué hace esta línea? (Declare una función: ¿qué nombre, qué parámetros y tipo de devolución? ¿Cómo llamarlo?)

Foo(b)(int (Bar*c));

¡Gracias de antemano por ayudarme!


Esto declara una función llamada b que:

  • toma int (Bar*c) como su argumento;
  • vuelve Foo .

El tipo de argumento, int (Bar*c) , es un puntero a una función que toma un puntero a Bar y devuelve un int . Aquí, c es el nombre del argumento y puede omitirse: int (Bar*) .

A continuación, le indicamos cómo puede llamar a b :

int main() { struct Foo {}; struct Bar {}; Foo(b)(int (Bar* c)); // the prototype in question int func(Bar*); // a function defined elsewhere Foo result = b(func); return 0; }


Esto no es válido C (porque los nombres Foo y Bar no hacen referencia a los tipos; tendrías que usar la palabra clave struct o usar un typedef).

En C ++, esta es una declaración sorprendente pero válida. Declara b como una función que devuelve Foo y toma un argumento de tipo "(puntero a) devolviendo la función int tomando un argumento de tipo puntero a Barra".

Para generar una declaración de tipo legible, he escrito el siguiente código:

#include <typeinfo> #include <iostream> int main() { struct Foo {}; struct Bar {}; Foo(b)(int (Bar*c)); std::cout << typeid(b).name(); return 0; }

Luego lo compilé y c++filt su salida a través de c++filt . El resultado fue:

main::Foo (int (*)(main::Bar*))

lo cual es completamente claro.


En realidad, mi compilador (Clang 3.5) me da la siguiente advertencia:

advertencia: los paréntesis fueron desambiguados como una declaración de función [-Wvexing-parse]

Lo cual es más acertado, ya que estás lidiando con el análisis más irritante .

La siguiente declaración:

Foo(b)(int (Bar*c));

declara un puntero de función b apuntando a una función que devuelve Foo y toma como argumento una función que devuelve int y toma el puntero a Bar un argumento (por ejemplo: int (Bar*c) ).

Su compilador probablemente piensa que este es un prototipo de una función, por lo tanto, la advertencia.