2009-09-13 10 views
5

J'ai trouvé une utilisation intéressante d'un typedef dont je n'ai pas vraiment besoin.typedef'ing un tableau vs en utilisant une struct en C++

typedef int Color[3]; 

Alors l'utilisation serait:

Color pants; 
pants[0] = 0; 
etc. 

Utilisation du typedef par REE a été la création d'un code étrange à la recherche qui n'a pas été clair.

Pourquoi ne pas simplement utiliser une struct?

struct Color { 
int r; 
int g; 
int b; 
}; 

Color pants; 
pants.r = 0; 
etc. 

Vous pouvez utiliser un syndicat pour exprimer les vars comme un tableau ou individuellement, ce qui est bancal, mais toujours clair qu'il est en quelque sorte plus complexe qu'une seule valeur. Est-ce que quelqu'un peut donner un aperçu du mérite de l'utilisation du tableau typedef'd par rapport à struct?

Répondre

3

Vous souhaitez que l'expression du tableau puisse être en boucle. Donc, si vous devez avoir les formes [rgb], vous utilisez une union, mais cela fait plus de dactylographie.

:: soupir ::

8

Peut-être que la structure n'a pas été aligné la façon dont le codeur d'origine voulu. peut-être qu'il était rembourré à 16 ou 32 bits. La création du tableau garantit qu'aucun rembourrage de structure n'a lieu. Cela a-t-il été transmis à un pilote ou à un périphérique matériel?

+1

Nice. Fonctionne sans se soucier des drapeaux de compilation ou des 'pragma's – dmckee

2

Le remplissage éventuel peut devenir un problème lors de l'utilisation d'un tableau de structures, car vous risquez de rencontrer des problèmes de conversion entre celui-ci et les cibles qui attendent des RGB très compressés. Dans ce cas, assurez-vous que le remplissage est exactement ce que vous attendez, en utilisant par exemple pragma pack(). Pour savoir si .x ou [] est meilleur, vous pouvez surcharger operator[] pour la structure (en utilisant un commutateur dans ce cas)

N'importe quel compilateur décent optimisera ceci pour être équivalent à static_cast<int*>(this)[index], donc il n'y a aucune perte de performance. Vous pouvez bien sûr aller avec le syndicat, mais cela n'aide pas beaucoup. Une autre possibilité consiste à implémenter .x() etc. en termes de [].

Quoi qu'il en soit, je vous recommande d'utiliser la struct, que vous ne lâche rien (vous pouvez toujours convertir un tableau de Color à int*, mais vous pouvez écrire des algorithmes plus facile lorsque vous prenez une struct que lors de la prise d'un int* - pour par exemple, si vous voulez de la luminance, il est plus facile pour IMAO d'avoir un bon membre/fonction libre en prenant une couleur au lieu d'un int *, car avec l'int, vous ne pouvez jamais être sûr que c'est RVB, RGBA, YoCoCg peut appliquer que.

Last but not least, un struct vous donne la possibilité d'initialiser tous les membres à des valeurs valides/sain d'esprit/debug, carrement.

5

Un autre avantage de la forme struct: si vous avez besoin de passer de la couleur à une fonction, puis prendre sa taille:

void foo (Color c) 
{ 
    size_t s = sizeof(c); 
} 

Si vous utilisez le formulaire de tableau, c est interprété comme un Color * (les tableaux sont passés via un pointeur vers leur premier élément) et sizeof(c) sera égal à sizeof(int*). Été là, fait cela, a été mordu là.Edit: la forme de la structure se comportera comme naïvement attendue.

+0

pourquoi ne pas simplement faire sizeof (Couleur)? – newacct

+0

Si vous changez le type de la variable, vous n'aurez pas besoin de mettre à jour le code dans deux (ou plusieurs) endroits. Oui, je sais que multi-search-replace, sed et Visual Assist sont vos amis mais je préfère ne pas m'en préoccuper. – LaszloG

7

L'utilisation de tableau simple est une mauvaise idée pour plusieurs raisons.

  • Le type int[] désintègre à int * lorsqu'il est utilisé dans la liste des paramètres. Vous ne pouvez pas utiliser operator= pour affecter des tableaux.

ou boost::array servirait beaucoup mieux le but.

+3

+1 Sauf qu'il ne se désintégrera pas lorsqu'il est passé par référence, pour ajouter de la confusion. – UncleBens

+0

UncleBens: upvoted votre commentaire: très vrai. Une discussion plus approfondie peut être trouvée sur SO ici: http://stackoverflow.com/questions/1328223/sizeof-array-passed-as-parameter – LaszloG

+0

Sauf si les exigences matérielles requièrent un alignement spécifique. Alors cela fonctionne parfaitement. –

0

Je suppose que le tableau a été utilisé comme un tuple, donc boost :: tuple pourrait être considéré comme une alternative qui montre mieux l'intention.

Questions connexes