2008-10-13 4 views
2

J'essaie de comprendre pourquoi ce qui suit ne fonctionne pas. J'ai un std :: vecteur et je veux appeler une fonction membre statique de celui-ci est contenu value_type comme ceci:Appel d'une fonction membre statique d'un conteneur STL C++ valeur_type

std::vector<Vector> v; 
unsigned u = v.value_type::Dim(); 

où le vecteur est en fait un typedef pour un type basé sur un modèle:

template <typename T, unsigned U> class SVector; 
typedef SVector<double, 2> Vector; //two-dimensional SVector containing doubles 

et la fonction membre statique Dim() insère réellement la dimensionnalité U du Vecteur.

Maintenant, le compilateur renvoie un message d'erreur indiquant:

error: ‘SVector<double, 2u>’ is not a base of 
‘std::vector<SVector<double, 2u>, std::allocator<SVector<double, 2u> > > 

qui me déconcerte. Je peux remplacer la ligne offenser apparemment par

unsigned u = Vector::Dim(); 

et qui fonctionne, mais il est évidemment laid comme hardcodes hypothèses sur la value_type de v ... Merci!

Répondre

15

Vous accédez au type de valeur par l'intermédiaire de l'instance de variable et non du type de variable.

Méthode 1 - cela fonctionne:

typedef std::vector<Vector> MyVector; 
MyVector v; 
unsigned u = MyVector::value_type::Dim(); 

Méthode 2 - ou ceci:

std::vector<Vector> v; 
unsigned u = std::vector<Vector>::value_type::Dim(); 

Si vous TypeDef aimez la méthode 1 vous ne coder en dur pas d'hypothèses sur le paramètre template vecteur et vous écrivez du code propre.


Edit: élargi pour expliquer le comportement de cette question comme demandé par le propriétaire de la question:

L'opérateur de résolution de portée :: a plus precedence que tout autre opérateur C++. Cela inclut l'accès Membre d'un opérateur .. Ainsi, lorsque vous écrivez quelque chose comme:

unsigned u= v.value_type::Dim(); 

cela résout au code C++ suivant:

unsigned u = v.SVector<double, 2>::Dim(); 

et, finalement, ce qui est résolu en premier est la partie SVector<double, 2>::Dim(). Cela forcerait l'instance de vecteur déclarée variable à l'entrée v à avoir une classe interne nommée SVector. Et parce que cela ne se produit pas traduit par erreur:

error C2039: 'SVector<double,2>' : is not a member of 'std::vector<_Ty>' 

STL vector devrait être « élargi » pour chaque utilisation de ce modèle (accès à l'instance variable creux value_type et non de type variable). Ce n'est pas une bonne solution car elle conduit à beaucoup de passe-partout et code inutile et non maintenable. En suivant les solutions mentionnées ci-dessus, vous évitez tout cela et pouvez facilement faire ce que vous vouliez.

+0

Merci beaucoup, c'est génial.Je ne savais pas qu'il n'était pas autorisé à accéder à value_type via l'instance. Seriez-vous par hasard savoir pourquoi cela n'est pas autorisé (ce qui irait mal si c'était permis)? – yungchin

+0

@yungchin vérifier si l'explication que je viens d'ajouter est suffisamment claire à propos de ce problème. –

+0

rien ne se passerait mal si elle était autorisée - puisque C++ est statiquement typé, il sait déjà que v est un std :: vector , mais là encore vous savez déjà ce que vaut v, donc cela ne fait vraiment aucune différence. Je suppose que les concepteurs C++ voulaient une séparation claire entre les membres statiques et les membres de l'instance. –