est-il en sécurité à Membecopy myvect.Size () * Tailleof (FOO) octets de la MemieDrach du premier élément d'un dans un tableau de p> struct foo{
T1 first;
T2 second;
}
3 Réponses :
Non, une classe contenant t1 code> et
t2 code> n'est pas garantie la même disposition ou alignement que
std :: paire
std :: paire code> n'est pas un type de pod). L'histoire peut être différente en C ++ 0x. P>
Mais STD :: paire n'est tout simplement pas de pod car il a un constructeur défini par l'utilisateur, non? Et cela ne devrait pas changer quelque chose sur la mise en page de la mémoire - ou le fait-il?
En C ++ 98, des implémentations sont autorisées à utiliser une disposition différente pour les types de pod non-POD par rapport aux types de POD. En C ++ 0X, si je me souviens bien, il existe une désignation spéciale pour les types qui ont des constructeurs, mais n'ont pas de classes de base, de fonctions virtuelles ou de membres non passionnés. Je ne me souviens pas de son nom, mais l'idée est que ces types sont suffisamment simples pour être Memcpy Code> capable.
@Chris: la mise en page standard, mais une classe de mise en page standard n'est pas nécessairement i> sans danger pour la copie, cela signifie simplement (en vigueur) que le compilateur n'a inséré aucune mauvaise surprise. Une classe RAII contenant un pointeur à un objet alloué en tas, qu'elle libère de la destruction et des clones sur la mission, est la mise en page standard mais non pod, et ne devrait probablement pas être copiée avec MEMCY.
@Steve: Merci d'avoir expliqué! Beaucoup plus clair que tout ce que j'aurais pu écrire. :-)
Mat doit également noter qu'il est correct de faire le memcpy () code> si le
myvect code> est de type
std :: vecteur
std :: copy (copy (copy (COPY> est utilisé à la place de
memcpy () code>.
@Michael: Seulement si struct foo code> est un type de pod. :-P (qui, pour cette question, signifie que
t1 code> et
t2 code> est également.)
Et c'est pourquoi STD :: Copy a intérêt à plus que des puristes - il copie des données non-POD.
@Chris: Droite - J'ai négligé ce détail (plutôt, j'ai supposé qu'ils étaient des types de pods - une hypothèse dangereuse). Cependant, std :: copie () code> fonctionnerait même s'il ne s'agit pas de POD (tant que le type prend en charge l'affectation). Donc, cela fait mal que mon fissure «puriste» - il devrait simplement être utilisé. Espérons que les optimisations empêchent le compilateur de cracher
memcpy () code> Code équivalent si les types sont POD - Je vais devoir jeter un coup d'œil à une sortie ASM pour voir si cela se produit vraiment dans la pratique. En tout état de cause, la sortie serait probablement suffisamment bonne sauf si ce n'est pas (comment est-ce pour l'agitation des mains?).
En fait, certains compilateurs Créer un code pour std :: copy (copy (copy (copy (copy (copy (copy (copy (copy> c'est meilleur i> que
std :: memcpy () code> - il est facile pour les spécialisations de
Std :: Copie () Code> Pour bénéficier des restrictions d'alignement de type. Par exemple.
STD :: Copie
En général, non. Sur certaines plates-formes / compilateurs / implémentations stl, cela pourrait être, mais ne le faites pas de toute façon. Vous deviez compter sur les détails de la mise en œuvre des deux paires <> et le vecteur <>. P>
J'ai moi-même commis le péché de compter sur le vecteur <> étant un tableau contigu. Pour cela, je me repentant profondément. Mais la paire <> ... Dites simplement non. P>
En fait, le vecteur <> est garanti d'être un tableau contigu.
Il est presque admis que std :: vecteur
& VEC [0] code> doit être utilisable comme Un tableau de taille
Vec.Size () code>. Mais, faire
memcpy code> sur des types non-pod tels que
std :: paire code> est risqué, oui.
Vous êtes pardonné, même en C ++ 03 ... std :: vecteur est requis pour utiliser le stockage contigu.
@Seva: à partir du projet de norme C ++ 03 23.2.5, "Les éléments d'un vecteur sont stockés contiguës, ce qui signifie que si v est un vecteur
@Seva: C ++ 03, 23.2.4.1: Les éléments d'un vecteur sont stockés contiguës, ce qui signifie que si v est un vecteur
Quelques autres liens pour plus d'informations sur contigus
Merci a tous. Je ne rappelle pas exactement le timing du péché en question - peut-être que c'était avant l'année 03, peut-être après. Quoi qu'il en soit, je me sentais mal à l'aise à l'époque.
std :: vecteur <> code>: Stackoverflow.com/questions/247738/... et Herbsutter.WordPress.com/2008/04/07 / ...
La réponse à la question que vous n'avez pas posée est probablement ou std :: transformer code>:
std :: copie code> , mais donnez FOO un
opérateur = code> prendre une paire comme paramètre. Cela suppose que vous pouvez ré-écrire FOO, bien que: P>
struct foo {
T1 first;
T2 second;
foo &operator=(const std::pair<T1,T2> &p) {
first = p.first;
second = p.second;
return *this;
}
};
std::copy(myvect.begin(), myvect.end(), myarray);
STD :: Transform () code> est quelque chose que je ne me souviens jamais. Déjà. Peut-être que maintenant que j'ai dit cela publiquement, ça va parfois me pousser dans ma tête.
STD :: Transform Code> Est ce que vous obtenez au lieu de la carte et de ZipWith. Donc, peut-être que si chaque fois que vous oubliez de transformer, vous réécrivez la fonction pertinente de HASKELLL, vous vous en souviendrez. Si seulement pour éviter d'écrire Haskell.
std :: paire est une structure, la norme dit que le compilateur détermine la mise en page bien que la commande doit être maintenue, donc dans l'instance de STD :: paire Votre compilateur peut décider de placer un rembourrage de 3 octets après chaque char Pour un alignement optimal, non vous ne pouvez pas supposer la mise en page de mémoire contiguë - fin de l'histoire.