2009-08-25 4 views
8

Dans VC++ quand j'ai besoin de spécifier un tableau lié à une variable membre de la classe je le fais de cette façon:Est-ce que tous les compilateurs C++ permettent d'utiliser une variable membre de la classe const int statique en tant que tableau lié?

class Class { 

private: 
    static const int numberOfColors = 16; 
    COLORREF colors[numberOfColors]; 
}; 

(s'il vous plaît ne me dites pas sur l'utilisation de std :: vecteur ici)

Cette comme j'ai une constante qui peut être utilisée comme un tableau lié et plus tard dans le code de la classe pour spécifier les contraintes d'instruction de boucle et en même temps il n'est pas visible nulle part ailleurs.

La question est de savoir si cette utilisation de variables membres static const int est autorisée uniquement par VC++ ou est-elle généralement autorisée par d'autres compilateurs répandus?

+8

"s'il vous plaît ne me parlez pas de l'utilisation de std :: vector ici" - non, ce ne serait pas approprié. Vous devriez utiliser 'std :: tr1 :: array'. ':)' – sbi

Répondre

4

Oui, il est 100% légal et devrait être portable. La norme C de dit cela en 5.19 - Les expressions constantes »(mine d'importance):

En plusieurs endroits, C++ exige expressions qui à une constante intégrale ou énumération: les limites du tableau (8.3.4, 5.3.4) , en tant qu'expressions de cas (6.4.2), en tant que longueurs de champ de bits (9.6), en tant qu'initialisateurs d'énumérateur (7.2), en tant qu'initialisateurs de membres statiques (9.4.2) et en tant qu'arguments de modèle intégral ou énumération non-type (14.3) .

constant-expression: 
    conditional-expression 

Une expression intégrale de constante peut impliquer seulement littéraux (2,13), les enquêteurs, variables const ou des membres de données statiques de types intégrale ou énumération initialisés avec expressions constantes (8.5), paramètres de modèle non-type de types intégral ou d'énumération et expression sizeof.

Cela dit, il semble que VC6 ne le supporte pas. Voir StackedCrooked's answer pour une bonne solution de contournement. En fait, je préfère généralement les mentions StackedCrooked de la méthode enum pour ce type de chose.

En tant que FYI, la technique "static const" fonctionne dans VC9, GCC 3.4.5 (MinGW), Comeau et Digital Mars.

Et n'oubliez pas que si vous utilisez un membre "` static const '", vous aurez need a definition for it in addition to the declaration à proprement parler. Cependant, pratiquement tous les compilateurs vous laisseront échapper en sautant la définition dans ce cas.

1

J'ai cessé de m'inquiéter de la portabilité de cette année. Il y a peut-être encore des compilateurs qui ne le soutiennent pas, mais je n'en ai rencontré aucun récemment.

13

Ce comportement est valide selon la norme C++. Tout compilateur récent devrait le soutenir.

6

Cela a été C++ standard depuis plus d'une décennie maintenant. Il est même soutenu par VC - que voulez-vous de plus? (@Neil: Qu'en est-il de SunCC? :^>)

6

Je crois que Visual Studio 2005 et au-delà le supporte. Le compilateur XCode C++ aussi (c'est gcc en fait).

Si vous voulez être sûr, vous pouvez toujours utiliser l'ancien hack enum que j'ai appris à partir de C++ efficace. Il va comme ceci:

class Class { 

private: 
    enum { 
     numberOfColors = 16 
    }; 
    COLORREF colors[numberOfColors]; 
}; 

Espérons que cela aide.

+0

Même VS 2k3 le supporte. – sharptooth

+0

L'enum 'hack' ne devrait pas être nécessaire si vous traitez du code C++, mais si vous voulez que la déclaration fonctionne en C ou en VC++ 6, c'est mieux que la méthode plus courante d'utiliser #define dans mon avis. –

2

Je suis assez sûr que cela fonctionnera aussi avec gcc et Solaris, mais je ne peux pas le vérifier pour le moment.

À l'avenir, vous pourriez étendre l'idée comme ceci:

template<int size> 
class Class { 
private: 
    COLORREF colors[size]; 
}; 

et l'utiliser comme ceci:

Class<5> c; 

de sorte que vous n'êtes pas limité à un seul taille de la mémoire tampon dans votre application.

+0

Vous utilisez un nombre magique, ce que la question essayait d'éviter. –

+0

@Neil: Cependant, le nombre magique 5 ci-dessus pourrait être remplacé par un static const int d'une classe dont 'c' pourrait se trouver membre. – quamrana

-1

Il est possible de répondre à des questions de ce genre en faisant référence à la spécification ISO C++, mais la spécification est difficile à lire pour les utilisateurs. Je pense que la réponse la plus simple repose sur deux choses:

  • Microsoft Visual Studio 2005 et jusqu'à la mise en œuvre est une relativement conforme C++. Si cela vous permet de faire quelque chose, les chances sont sa norme.
  • Téléchargez quelque chose comme Code :: Blocks pour obtenir un compilateur GCC pour essayer des choses. Si cela fonctionne dans MS et GCC, les chances sont vraiment, sa norme.
+0

La spécification est très facile à obtenir (pour 30 $): http://stackoverflow.com/questions/81656/where-do-i-find-the-current-x-standard/83763#83763 Lire la spécification est un autre histoire, mais les prgrammers C++ sérieux devraient probablement toujours s'y référer de temps en temps: http://stackoverflow.com/questions/1123455/should-every-c-programmer-read-the-iso-standard-to-become-professional –

13

Ceci est valide en C++ et la plupart des compilateurs raisonnablement modernes le supportent.Si vous utilisez coup de pouce, vous pouvez obtenir un soutien portable pour cette fonction sous la forme de BOOST_STATIC_CONSTANT macro:

class Class { 
private: 
    BOOST_STATIC_CONSTANT(int, numberOfColors = 16); 
    COLORREF colors[numberOfColors]; 
}; 

La macro est étendu à static const int numberOfColors = 16 si le compilateur prend en charge, sinon il recourt à enum { numberOfColors=16 };.

3

Outre d'autres réponses que vous pouvez utiliser la fonction suivante ne déterminer le nombre d'éléments dans les tableaux statiquement alocated:

template<typename T, size_t length> 
size_t arrayLength(T (&a)[length]) 
{ 
    return length; 
} 
Questions connexes