2011-01-28 9 views
21

Quiero declarar la definición de tipo para una firma de función miembro. typedefs función globales se ven así:sintaxis de firma de función de miembro CTY typedef

typedef int (function_signature)(int, int); 
typedef int (*function_pointer) (int, int); 

pero no soy capaz de lo mismo para una función miembro:

typedef int (foo::memberf_signature)(int, int); // memberf_pointer is not a member of foo 
typedef int (foo::*memberf_pointer)(int, int); 

Suena lógicamente a mí, porque "foo ::" Ist el sintaxis para acceder a un miembro en la clase foo. ¿Cómo puedo tipear solo la firma?

+0

Sólo por curiosidad, ¿por qué ¿Estás tratando de hacer esto? –

+4

Estoy confundido, ¿el último 'typedef' no es lo que quieres? – GManNickG

+0

Eso no me parece homogéneo. Es posible escribir una función declarada en global-scope, pero no es posible escribir un método dedef. Y sí, estoy diferenciando entre una firma y un tipo de puntero a función. – 0xbadf00d

Respuesta

10

preguntas sobre la sintaxis de puntero de función incómoda, yo personalmente uso una hoja de trucos: The Function Pointers Tutorial (downloadable here, gracias a Vector para señalarlo).

La firma de una función miembro, sin embargo, es un poco diferente de la firma de una función normal, como usted experimentó.

Como probablemente sepa, una función miembro tiene un parámetro oculto, this, cuyo tipo debe especificarse.

typedef int (Foo::*Member)(int, int); 

Qué le permiten especificar que el primer elemento pasa a la función será un Foo* (y por lo tanto su método realmente toma 3 argumentos, cuando se piensa en ella, no sólo 2.

Sin embargo, hay otra razón, por lo que obligó a especificar el tipo.

un puntero de función podría referirse a una función virtual, en el que las cosas de casos pueden llegar a ser muy complicado. por lo tanto, el tamaño de la en-memoria representación cambia dependiendo en el tipo de función. De hecho, en Visual S tudio, el tamaño de un puntero a función puede variar entre 1 y 4 veces el tamaño de un puntero normal. Esto depende de si la función es virtual, en particular.

Por lo tanto, la clase a la que se refiere la función es parte de la firma, y no hay solución alternativa.

+0

su enlace está roto –

+0

@ BЈовић: y era un enlace tan bueno también ... oh, afortunadamente, sabía un segundo artículo;) –

+0

Nuevo enlace de trabajo con _downloads_ para [** The Function Pointers Tutorial **] (http: //www.newty.de/fpt/dload.html) – Vector

1

La razón por la que no funciona con su sintaxis actual es que la precedencia del operador dicta que se está refiriendo a una función llamada foo::memberf_signature, no a ningún tipo de tipo.

No estoy seguro si puede hacer esto o no, pero no pude encontrar ninguna combinación de parenthese que indujera al código a compilar con g ++ 4.2.

+0

¿Qué tal si solo ':: memberf_signature' tal vez? – user470379

-3

Bueno, básicamente no puede funcionar (al menos no sé de ninguna manera con g ++); Usando el compilador de Borland C++, estaría la palabra clave __closure.

La razón por la que no se compila es que el tamaño de la funciónpointer (en una máquina x86) ocupa siempre < < 32bits >>; pero si desea apuntar a una firma de clase (interfaz), el tamaño debe ser de 64 bits: 32 bits para este puntero (ya que la interfaz de clase está en la memoria solo una vez) y 32 bits para la función real

pero la palabra clave __closure es un lenguaje BCB 'hackear' no estandarizados ...

+0

El hecho de que los punteros de función de miembro y los punteros de función sean de diferentes tamaños me parece irrelevante. Típicamente, 'short' y' double' son de diferentes tamaños, pero puede 'typedef' con ambos. –

+1

El puntero 'this' se pasa normalmente como primer parámetro oculto. No he oído hablar de ningún compilador que utilice un puntero de 64 bits para convertir este puntero en el puntero a un objeto. –

+0

Eso es absolutamente incorrecto. Este puntero se almacena en el registro ECX (por ejemplo, MSC) en la máquina de destino IA-32. Cualquier puntero es siempre de 32 bits en dicho sistema. – 0xbadf00d

2

funciona para mí:

#include <iostream> 

class foo 
    { 
public: 
    int g (int x, int y) { return x + y ; } 
    } ; 

typedef int (foo::*memberf_pointer)(int, int); 

int main() 
    { 
    foo f ; 
    memberf_pointer mp = &foo::g ; 
    std::cout << (f.*mp) (5, 8) << std::endl ; 
    } 
+0

Es un typedef para un puntero de función miembro. Ese trabajo es para mí también, pero no es lo que busco;) – 0xbadf00d

+0

OK, ahora veo lo que quieres. Pero, ¿cómo planeas usar este typedef, si logras crearlo? – TonyK

3

Puede factorizar la clase de destino en C++ moderna (puesto 11) mediante la utilización de la '' typedefing cualidades de alias plantilla. Lo que necesita se vería como:

template<typename T> 
using memberf_pointer = int (T::*)(int, int); 

Sin embargo, en el momento de la declaración, un puntero a la función miembro de la utilización de esta sintaxis sería necesario especificar la clase de destino:

// D is a member function taking (int, int) and returning int 
memberf_pointer<foo> mp = &foo::D; 
Cuestiones relacionadas