Problème liste de template
Bonjour à tous,
Après un retour de vacances je me remets au boulot et me retrouve confronté aux problèmes d'avant de partir :aie:
Pour vous exposer mon problème je vais synthétiser les étapes de mon problème.
Je dois faire un programme ou l'utilisateur crée des variables.
Au départ mon responsable m'avait dit d'utiliser une structure pour stocker la variable comme ceci :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| enum TYPE_CODAGE
{
LIBRE = 0,
ENT,
ENT_S,
REEL,
ENUM,
BOOLEEN,
ASCII,
TABLEAU,
COMPLEXE,
FICHIER_TECHNIQUE,
};
struct sData
{
TYPE_CODAGE type;
long long valeur;
}; |
Et quand je devais crée une variable je faisais un truc du genre :
Code:
1 2 3 4 5 6 7 8 9 10 11
| QVector<sData> datas;
sData data1;
sData data2;
//Si l'utilisateur a crée un int
data1.TYPE_CODAGE = ENT_S;
*(data1.valeur) = reinterpret_cast<long long*>(&MonInt);
//Si l'utilisateur crée un float
data2.TYPE_CODAGE = REEL;
*(data2.valeur) = reinterpret_cast<long long*>(&MonFloat);
datas.push_back(data1);
datas.push_back(data2); |
Bon voila c'était pas opti je pense surtout que je devais caster à tout va. Pour stocker ou lire les variables dans le type souhaité.
Puis je suis passé à un truc comme ca :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13
| union Type
{
qint64 tInt;
quint64 tUInt;
double tDouble;
char tChar[8];
};
struct sData
{
TYPE_CODAGE type;
Type valeur;
}; |
Et quand je devais crée une variable je faisais un truc du genre :
Code:
1 2 3 4 5 6 7 8 9 10 11
| QVector<sData> datas;
sData data1;
sData data2;
//Si l'utilisateur a crée un int
data1.TYPE_CODAGE = ENT_S;
data1.valeur.tInt = MonInt;
//Si l'utilisateur crée un float
data2.TYPE_CODAGE = REEL;
data2.valeur.tDouble = monFloat;
datas.push_back(data1);
datas.push_back(data2); |
C'était un peu mieux mais bon le problème c'est que quelque soit le type, la valeur est stockée sur 8octets. Si on veut un int et qu'on le stocke dans 8octets cela pose problème quand on veut ensuite l'écrire une fonction comme ceci :
Code:
1 2 3 4 5 6 7 8 9 10 11
| template <class T>
void read(T& val, const unsigned char* data, int msb, int lsb, bool big_endian=true)
{
const size_t size = sizeof(T);
typedef typename unsigned_<size>::type type;
type *ptr = reinterpret_cast<type*>(&val);
for(size_t i=0; i<size; ++i)
ptr[big_endian ? size-i-1: i] = data[i];
val <<= (sizeof(val) * CHAR_BIT - msb - 1);
val >>= lsb;
} |
On écrit 8octets même si la variable en contient moins.. Pas malin..
Donc j'ai eu une longue conversation avec koala01 qui m'a convaincu d'utiliser des templates pour ma structure. Cela donne :
Code:
1 2 3 4 5 6 7 8
| template <typename Type>
struct sData
{
/* ca, c'est juste pour pouvoir récupérer le type en cas de besoin ;) */
using value_type = Type ;
enum{accessSize = sizeof(Type)}; // la taille réellement utilisée en mémoire par Type (en bytes ;) )
value_type original; // la valeur d'origine (dans son type d'origine)
}; |
C'est niquel et cela colle avec la fonction readn !
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13
| sData data1;
sData data2;
//Si l'utilisateur a crée un int
sData<int> data1;
data1.original = MonInt;
//Si l'utilisateur crée un float
sData<float> data2;
data2.original = MonFloat;
/*Maintenant je veux stocker les deux structures dans une liste ou tableau (n'est ce pas un des principes de l'informatique? Regrouper ce qui se ressemble, qui a un lien.Donc j'essaye de faire cela :*/
QVector<Type> datas; // Je sais que c'est n'importe pas mais je vois pas comment faire..
//pour pouvoir faire:
datas.push_back(data1);
datas.push_back(data2); |
Voila où j'en suis, je n'arrive pas à regrouper mes structures templates. Car si c'est pour avoir une liste d'int, une de float, une d' unsigned int et les remplir en fonction du type template, non merci quoi !
J'ai l'impression d'être un peu f**ked et que finalement la meilleur solution était la première (ou finalement aucune des trois..)
Merci d'avance si quelqu'un a une solution.