2009-10-13 16 views
1

Il est similaire au problème à ce bogueC++ GCC 4.3.2 erreur sur le vecteur de char-tableau

Question about storing array in a std::vector in C++

mais pour une raison différente (voir ci-dessous).

Pour le programme exemple suivant en C++:

#include <vector> 

int main(int c_, char ** v_) 
{ 
     const int LENGTH = 100; 

     std::vector<char[LENGTH]> ca_vector; 

     return 0; 

} 

GCC 4.2.3 proprement compile. GCC 4.3.2 émet les erreurs suivantes:

 
/usr/lib/gcc/i686-pc-linux-gnu/4.3.2/include/g++-v4/bits/stl_construct.h: In function ‘void std::_Destroy(_Tp*) [with _Tp = char [100]]’: 
/usr/lib/gcc/i686-pc-linux-gnu/4.3.2/include/g++-v4/bits/stl_construct.h:103: instantiated from ‘void std::_Destroy(_ForwardIterator, _ForwardIterator) [with _ForwardIterator = char (*)[100]]’ 
/usr/lib/gcc/i686-pc-linux-gnu/4.3.2/include/g++-v4/bits/stl_construct.h:128: instantiated from ‘void std::_Destroy(_ForwardIterator, _ForwardIterator, std::allocator&) [with _ForwardIterator = char (*)[100], _Tp = char [100]]’ 
/usr/lib/gcc/i686-pc-linux-gnu/4.3.2/include/g++-v4/bits/stl_vector.h:300: instantiated from ‘std::vector::~vector() [with _Tp = char [100], _Alloc = std::allocator]’ 
test.cpp:7: instantiated from here 
/usr/lib/gcc/i686-pc-linux-gnu/4.3.2/include/g++-v4/bits/stl_construct.h:88: error: request for member ‘~char [100]’ in ‘* __pointer’, which is of non-class type ‘char [100]’ 

La raison est apparemment ce bit dans

include/g++-v4/bits/stl_construct.h

template 
    inline void 
    _Destroy(_Tp* __pointer) 
    { __pointer->~_Tp(); } 

qui est appelé, je pense que, en raison de mauvaise série à pointeur désintégration.

Ma question est: Existe-t-il quelque chose dans la norme linguistique empêchant le stockage des tableaux dans std :: vector? Ou est-ce juste un bug dans cette version spéciale de GCC? Je crois que cela devrait compiler (c'est-à-dire que 4.2.3 est correct).

Merci martin

+0

Quelle est la raison pour laquelle vous n'utilisez pas std :: string? – kmarsh

+0

Voulez-vous dire que votre code a été compilé et exécuté correctement dans GCC 4.2.3? – fpmurphy1

+0

Il compile encore sur ce système, oui. Et cela semble fonctionner. – martin

Répondre

6

Oui, il y a quelque chose dans l'arrêt standard en utilisant des réseaux utilisant Draft C++98 Standard

Section 23 conteneurs

Le type d'objets stockés dans ces composants doivent satisfaire aux exigences des types CopyConstructible (20.1.3), et les exigences supplémentaires de Affignabletypes.

où les composants sont différents conteneurs

20.1.3 inclut l'exigence que le type doit avoir une destructor.

Je pense à cela comme un vecteur doit copier allouer et supprimer des éléments. Comment C++ sait-il copier ou supprimer un caractère []?

+0

Merci pour la référence, bon boulot. J'aurais dû le trouver moi-même, mais j'étais trop borné. D'autres réponses sont correctes aussi, je le signale, car c'était le plus rapide. respects martin – martin

+0

Je suis sûr que vous l'interprétez mal. 'std :: vector ' est très légal même si int n'a pas de destructeur non plus. – MSalters

+0

Vous pouvez faire x = new int (5): delete x; - mais pour supprimer un tableau vous devez supprimer [] – Mark

-1

S'il vous plaît laissez-moi savoir ce code. Vous le savez déjà, le vecteur est aussi une sorte de tableau et vous n'avez pas à donner la taille initiale.

1D vector -> std::vector<char*> ca_vector; 
2D vector -> std::vector<char*,char*> ca_vector; 
+0

Bonjour, merci pour la réponse. Je suis conscient que le vecteur peut être utilisé comme un tableau, comme vous l'avez correctement souligné. Ce que je voulais savoir, c'est si le code ci-dessus est légal au sens de la norme. J'aurais pu y mettre un vecteur de chaînes de caractères mais comme Mark l'a écrit, un tableau C/C++ de base ne remplit pas les exigences sur les éléments du conteneur. – martin

+0

@Aykut: std :: vector n'a aucun sens. – sellibitze

+1

Le deuxième argument de modèle à vector n'est pas le type de la deuxième dimension (les vecteurs ont seulement une dimension). Le deuxième argument est l'allocation (par défaut à l'allocateur standard). –

2

Non, ce n'est pas autorisé, tout comme il n'a pas été autorisé à la question que vous allez rejoindre (et je ne vois pas comment la « raison est différente »). Ce n'est pas un "bug" dans l'une ou l'autre des deux questions. Ou au moins, pas un bug dans le compilateur. Juste dans votre code. ;)

Vous ne pouvez pas stocker un tableau dans un vecteur, car un vecteur requiert que ses éléments soient constructibles par copie et affectables.

2

La solution pour ce faire est plus facile:

std::vector<boost::array<LENGTH> > ca_vector; 

De cette façon, vous n'avez pas à se soucier de l'histoire tableau/pointeur. Que vous le vouliez vraiment, c'est une autre question.

+0

En fait, dans mon cas concret, le vecteur est la solution (probablement voulue) du problème dans le code source (ancien) que j'examine (donc ce ne sont pas des octets bruts ou autre chose que des chaînes). Je ne suis pas du tout sûr pourquoi il y a même un tableau char [] - et pas une chaîne, quand il y a déjà un vecteur, je ne peux qu'imaginer des considérations d'optimisation obscures (et probablement erronées) sur l'auteur original ... – martin

+0

S'il s'agit d'une chaîne, utilisez une chaîne.J'ai utilisé ma construction comme solution temporaire pour stocker des messages basés sur des octets dans un conteneur stl – stefaanv

+0

ou std :: vector > ca_vector; –