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.