Operador de conversión C ++ para convertir puntero a función

He estado moliendo mi cabeza contra una idea que es lo suficientemente simple en mi cabeza, pero no puedo averiguar cómo implementar en C ++.

Normalmente, puedo declarar una clase con un operador de conversión como en este simple ejemplo:

class Foo { private: int _i; public: Foo( int i ) : _i(i) { } operator int( ) const { return i; } }; 

Así que ahora puedo escribir cosas impresionantes como

 int i = Foo(3); 

Pero en mi caso particular, me gustaría proporcionar un operador para convertir un objeto en un puntero de función (por ejemplo, convertir una instancia de Bar en un puntero de función int(*)(int, int) ). Esto es lo que inicialmente intenté:

 class Bar { private: int (*_funcPtr)(int, int); public: Bar( int (*funcPtr)(int, int) ) : _funcPtr(funcPtr) { } operator int(*)(int, int) ( ) const { return _funcPtr; } }; 

Pero la función del operador no se comstack, con estos errores que se generan:

 expected identifier before '*' token '' declared as a function returning a function 

También he intentado variaciones simples en lo anterior, como rodear el tipo de retorno entre paréntesis, pero todas estas ideas también han fallado.

¿Alguien sabe cuál es la syntax para declarar un método de operador de puntero de conversión a función, o si es posible hacerlo?

Nota: Estoy comstackndo esto con Code :: Blocks usando GCC 4.5.2. Las respuestas relacionadas con algunos de los nuevos conceptos de C ++ 0x también son bienvenidas.

Editar

En mi esfuerzo por simplificar el ejemplo, sin querer omití un detalle. Es un poco raro, pero en lugar de devolver estrictamente un puntero int(*)(int,int) , el operador de conversión está destinado a tener plantillas:

 template operator ReturnType(*)(ArgType1, ArgType2) ( ) const { // implementation is unimportant here } 

Por lo que sé, ya no puedo tipear este tipo de letra. Esto claramente hace que las cosas sean mucho más torpes, pero espero que todavía haya un camino.

Como debes saber:

 (*operator int() const)(int, int) { return _funcPtr; } 

(Corregido. Otra vez.)


Actualización: Johannes Schraub y Luc Danton me informaron que esta syntax no es válida y que realmente debe usar typedef. Ya que dice que typedefs no son una opción, aquí hay una clase auxiliar que puede envolver su typedef:

 template struct MakeFunctionType { typedef R(*type)(A1, A2); }; template operator typename MakeFunctionType::type () const { // implementation is unimportant here } 

Utilice un typedef. Es más fácil de leer, de todos modos:

 class Bar { public: typedef int (*fptr_t)(int, int); Bar(fptr_t funcPtr) : _funcPtr(funcPtr) { } operator fptr_t() const { return _funcPtr; } private: fptr_t _funcPtr; }; 

[editar]

Para el caso de su plantilla no veo cómo usar typedef. @Kerrik da la versión (desordenada) de la syntax que debería funcionar.

EDITAR:

Dado que su clase tiene un puntero de función no plantilla asignado en la construcción:

 private: int (*_funcPtr)(int, int); 

No es posible convertirlo más tarde en un puntero de función de cualquier tipo.

Por lo tanto, asumiré que se refería a una sobrecarga de operador miembro de clase de plantilla, no a una sobrecarga de operador de miembro de plantilla de clase.

Versión de plantilla:

 template class Bar { public: typedef ReturnType (*fptr_t)(ArgType1, ArgType2); operator fptr_t ( ArgType1 arg1, ArgType2 arg2 ) const { // implementation is unimportant here } //etc... }; 

Luego se usa así:

 //create functor to some function called myfunc Bar::fptr_t func_ptr = Bar(&myfunc); //call functor int i = func_ptr(1,2); 

Si desea que el código sea legible, debe utilizar un typedef. Ni siquiera uso punteros de funciones sin escribirlas, la syntax es demasiado horrible.

Gol:

 template operator ReturnType(*)(ArgType1, ArgType2) ( ) const { return 0; } 

Camino:

 // 1: helper structure template  struct helper { typedef R (*type)(A0,A1); }; // 2: operator template  operator typename helper::type() const { return 0; } 

¡Échale un vistazo a ideone !

Los siguientes trabajos en GCC:

 template operator decltype((ReturnType(*)(ArgType1, ArgType2)) nullptr)() const { // ... } 

En C ++ 11, es posible usar una plantilla de alias para convertir a cualquier función, evitando la necesidad de struct rasgos de tipo personalizado.

 class Bar { private: template using funcptr = ReturnType(*)(ArgType1, ArgType2); public: template operator funcptr ( ) const; }; 

Para limitar esto a solo int(*)(int, int) , podemos usar SFINAE o static_assert .