Free Pascal – La clase genérica TFPGlist y su problema con los registros

Existe un problema poco conocido sobre el manejo de datos de tipo registro haciendo uso de listas genéricas de tipo TFPGList.

El problema se resume en que no es posible especializar directamente un TFPGList con datos de tipo Record. Por ejemplo si intentamos compilar el siguiente código:

program project1;

{$mode objfpc}{$H+}

uses  fgl;

type

TReg = record   //Titpo registro

   x: Integer;

end;

 type

TRegGen = specialize TFPGList<TReg>;  //Especializa

 begin

 end.

 

Obtendremos el mensaje: “Error: Operator is not overloaded: “TReg” = “TReg””.

No importa que tipo de registro usemos, no podremos especializar la lista con ese registro.

Este error está documentado como un “bug” de Free Pascal y tiene que ver con una limitación en el manejo de genéricos. Después de averiguar sobre el tema, al fin puedo proponer una solución.

 

Consiste en usar “registros avanzados” (Extended Record) de Free Pascal. Estos registros son una especie de versión avanzada de los viejos registros de Pascal. Permiten incluir métodos en él como si fueran objetos, pero no soportan herencia.

Usando estos registros avanzados, necesitamos definir el operador de comparación “=” que se debe usar para comparar a los nodos de tipo registro.

Es necesario incluir la directiva {$modeswitch advancedrecords}, en el programa:

Program project1;

 {$modeswitch advancedrecords}

 uses Classes, Fgl;

 type

 TReg = record   //Titpo registro

    x: Integer;

    class operator =(op1,op2: TReg) B: Boolean; //Operador de igualdad

 end;

 type

 TRegGen = specialize TFPGList<TReg>;   //Especializa

 class operator TReg.=(op1, op2: TReg)B: Boolean;

 begin

 B := (op1.x = op2.x);  //Compara registros

 end;

 begin

end.

Ahora con esta modificación, ya podemos compilar nuestro programa.

Sin embargo, recomendaría el uso de Clases en lugar de Registros, y usar la lista TFPGObjectList.

Puntuación: 0 / Votos: 0

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *