Créer une taille fixe std::vector et d'écrire sur les éléments
En C++ je souhaite allouer une taille fixe (mais la taille a été déterminée au moment de l'exécution) std::vector puis écrire les éléments de ce vecteur. C'est le code, je suis en utilisant:
int b = 30;
const std::vector<int> test(b);
int &a = test[3];
Cependant, ce qui me donne un compilateur (MSVC 2010 Pro) erreur:
error C2440: 'initialisation' : impossible de convertir de 'const int' int &". Conversion perd qualificatifs.
Ma compréhension de const, c'est qu'il fait toutes les variables membres d'une constante de classe. Pour exemple, le code suivant fonctionne:
class myvec
{
public:
myvec(int num) : ptr_m(new int[num]) {};
~myvec() { delete ptr_m; }
void resize(int num) { delete ptr_m; ptr_m = new int[num]; }
int & operator[] (int i) const { return ptr_m[i]; }
int *ptr_m;
};
const myvec test(30);
int &a = test[3]; //This is fine, as desired
test.resize(10); //Error here, as expected
Il semble donc que les std::vector propage la const-ness du conteneur pour les éléments du vecteur, ce qui semble étrange parce que si j'avais voulu les éléments à prendre en const, j'aurais utilisé std::vector<const int>
. Ce qui me frappe comme une lacune de std::vector.
En tout cas, comment puis-je créer un std::vector, dont la taille ne peut être modifiée après la construction, mais dont les éléments peuvent être écrites?
a
d'abord, puis de faire votre dernière ligne.Puis
a
n'est pas une référence. L'erreur est due à avoir une écriture référence à un élément du vecteur, ce qui est exactement ce que je veux.Vous devez essayer d'utiliser un
std::vector<const int>
... voir ce qui se passeOriginalL'auteur user664303 | 2013-04-05
Vous devez vous connecter pour publier un commentaire.
Ce n'est pas possible sans l'écriture de votre propre classe wrapper. Si vous souhaitez utiliser une plaine
std::vector
, vous devez compter sur l'auto-discipline, en n'utilisant pas les fonctions de membreinsert()
,push_back()
ouemplace_back()
, que ce soit directement ou indirectement (par exemple par l'intermédiaire d'unback_inserter
).Remarque qu'il y a une proposition pour les tableaux dynamiques pour le nouveau C++14 Standard:
La proposition vient avec une implémentation de référence que vous pouvez utiliser dans votre propre code (assurez-vous de changer
namespace std
en quelque chose d'autre pour le moment).const std::vector<int>
signifie la même chose queconst std::vector<const int>
, quand il pourrait plutôt dire exactement ce que le std::dynarray est proposé pour, renoncer à la nécessité d'un nouveau conteneur.Vous ne pouvez pas mettre un
const T
dans un récipient, car ce type n'est pas Cessible et viole par conséquent les Exigences relatives aux contenants. Mettreconst
devant le conteneur lui-même, désactive tous les non-const membre, y compris les fonctions de l'élément de mission. C'est pourquoi vous avez vraiment besoin d'un adaptateur de conteneur de manière sélective désactive seulement le redimensionnement des membres, ou d'un objet particulier de la classe commedynarray
.OriginalL'auteur TemplateRex
L'erreur est parce que vous déclarez le vecteur d'être constante, ce qui signifie que vous pouvez ne jamais modifier le contenu.
Ensuite, lorsque vous essayez d'obtenir un non-constante référence à une entrée dans le vecteur, le compilateur vous dit que vous ne pouvez pas faire cela, parce que vous pouvez changer la valeur de la constante stockées dans le vecteur.
Pour la création d'un vecteur avec une taille qui peut être fixé au moment de l'exécution, mais pas de modifier la taille après le vecteur a été créé, vous devez créer un conteneur de l'adaptateur. Fondamentalement, vous devez créer un wrapper autour d'un autre conteneur, comme par exemple
std::stack
.En faisant le vecteur
const
vous dire au compilateur que tous du vecteur est constant, non seulement la taille mais aussi son contenu.Clairement, dans le cas de std::vector, oui. Mais ce n'est pas la norme de comportement. Voir ma mise à jour de question. Alors, pourquoi ne std::vector le faire? Surtout en gardant à l'esprit que j'aurais utilisé un const type si je voulais const éléments. Personne n'a suffisamment justifié son comportement pour moi encore.
Pour résumer, pourquoi ne
const std::vector<int>
dire la même chose queconst std::vector<const int>
, quand elle pourrait signifier quelque chose de différent et de renoncer à la nécessité d'une nouvelle std::dynarray classe?Je n'ai pas vérifié la norme, mais les deux clang et GCC se plaint à ce sujet, donc je dirais c'est qu'ils façon dont il est censé être.
OriginalL'auteur Some programmer dude
La réponse directe est que vous ne pouvez pas le faire: vous ne pouvez pas définir le vecteur const puis d'ajouter des membres.
Comme d'autres l'ont souligné, la nouvelle norme offre le tableau de la classe, qui est probablement plus adapté pour ce que vous faites.
Si vous êtes intéressé par une longueur fixe, les plus méthode associée au vecteur vous pouvez être intéressé par est
reserve()
, sur lequel sera fixé levector<>
à la taille du paramètre donné, la prise de vecteur expansions inutiles.Si vous ne pouvez pas utiliser Std C++11, alors vous avez besoin de créer une classe wrapper qui ne vous permet pas de modifier le vecteur. Par exemple:
Espère que cette aide.
OriginalL'auteur Baltasarq