Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Puntero estático a función en plantilla de C++

Iniciado por Neodivert, 19 de Abril de 2009, 09:04:53 PM

« anterior - próximo »

Neodivert


Buenas amigos. Estoy desarrollando una plantilla para crear fracciones de cualquier tipo.  Al tratar de implementar un método para eventualmente simplificar dichas fracciones concluí que lo mejor sería disponer de un puntero a dicha función cuyos parámetros fueran el numerador y el denominador y que el programador que usara dicha plantilla le pasara dicha función. También debía tratarse de un puntero / función estática, para evitar tener varias fracciones del mismo tipo pero simplificadas de modo diferente. Después de consultar en varias páginas web y mediante el arcaico pero efectivo método de prueba-error  0:-) lo implementé de la siguiente forma.

cFraccion.cpp

template <class A>
class cFraccion {
    private:
        A Num, Den, Comun;
        static void (* Simplificar)( A& Num, A& Den );

    public:

        ...

};

...

// Función creada por mí para simplificar la fracción en el caso de que contenga números enteros.
inline void Simp( int &Num, int &Den ) ;


Prueba.cpp

#include"cFraccion.cpp"

void Simp( float &a, float &b ){
    a -= 1;  // Simplemente puse esto para comprobar que invocaba a la función correcta. ;-)
}

void Simp( char &a, char &b ){ // (1)
};

template <class A>
void (*cFraccion<A>::Simplificar)( A& Num, A& Den ) = Simp; // (2)

int main(){

    cFraccion<int> A ( 4, 2 );
    cFraccion<float> B ( 2.1, 1 );
    cFraccion<char> C ( 'a', 'b' );

    cout << A << endl
         << B << endl
         << C << endl;
}


El programa compila perfectamente, pero le veo un par de limitaciones:
En (1): Si alguien no desea tener un método para simplificar las fracciones, debe crear una función que no haga nada. Cosa que no veo "elegante".
En (2): Tal como declaro y defino el puntero estático, la función para simplificar tiene que tener siempre el mismo nombre "Simp". Esto en realidad no me "molesta", pero puede que haya una forma que de más "libertad".

Luego la pregunta es: ¿Hay una forma mejor de implementarlo?

¡Gracias!  ;)

P.D. "Por si colaba", probé con


template <class A>
void (*cFraccion<int>::Simplificar)( int& Num, int& Den ) = Simplicar_Enteros; // Renombrando la función obviamente.


pero me lanza un error: "internal compiler error: in output_constant, at varasm.c: 3866


Pogacha

Punteros a funciones en casos extremos de ultima necesidad lease optimizaciones complicadas.

Ya que vas a tener templates usa politicas, o sea:
Citar
template<class T> struct MiSimplificacion { 
   static void Simplificar(T& num, T& den)
  {
    // ACA escribis tu simplificacion
   } 
};

template<class T> struct NoSimplificar { 
   static void Simplificar(T& num, T& den)
  {
  // no hace nada
   } 
};

template<class T, class PoliticaDeSimplificacion = NoSimplificar> Fraccion
{
   T num, dem;
    Simplificar() {  PoliticaDeSimplificacion::Simplificar(num, dem); }
};
 

Fraccion<float>  m; // fracciones con flotantes que no se simplifican nunca

Fraccion<int, MiSimplificacion>  m; // fracciones con enteros que no se simplifican con MiSimplificacion

Libro a leer: Modern C++

Saludos

Neodivert

¡Muchas gracias !  :)

Pero cuando intento escribirlo así:


struct Simplificar_Enteros {
    static void Simplificar( int& Num, int& Den ){
        int Comun;
        if( Num && Den ){
            if( Den < 0 ){
                Num = -Num;
                Den = -Den;
            }
            Comun = mcd( ( ( Num > 0 ) ? Num : - Num ), ( ( Den > 0 ) ? Den : -Den ) );
            Num /= Comun;
            Den /= Comun;
        }
    }
};

template <class A>
struct No_Simplificar {
    static void Simplificar(A& num, A& den){
    }
};

template <class A, class Simplificacion = No_Simplificar>
class cFraccion {
    private:
        A Num, Den, Comun;
        static void Simplificar(){
            Simplificacion::Simplificar( Num, Den );
        }
        ...
};


me arroja el error "No_Simplificar is not a type" en la línea

template <class A, class Simplificacion = No_Simplificar>

¿A qué se debe?  ???

¡Gracias!

P.D. El libro parece interesante, veré si está por la biblioteca de la facultad.  :P

Pogacha

Me falto el <A>
template <class A, class Simplificacion = No_Simplificar<A> >

Neodivert







Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.