Insérer dans le vecteur d'avoir des objets sans constructeur de copie
J'ai une classe dont la copie constructeurs sont explicitement supprimé (car Un utilise des pointeurs en interne et je ne veux pas tomber dans la copie superficielle pièges):
class A {
public:
A(const A&) = delete;
A& operator=(const A&) = delete;
A(const B& b, const C& c);
}
Maintenant, j'ai un vecteur de type vector<A> aVector;
et je veux insérer des éléments dans il - donc j'utilise emplace_back
:
aVector.emplace_back(b, c);
Toutefois, cela ne parvient pas à le compiler avec gcc et j'obtiens l'erreur -
third-party/gcc-4.7.1-glibc-2.14.1/libgcc/libgcc-4.7.1/afc21dc/include/c++/4.7.1/bits/stl_construct.h: In instantiation of 'void std::_Construct(_T1*, _Args&& ...)
third-party/gcc-4.7.1-glibc-2.14.1/libgcc/libgcc-4.7.1/afc21dc/include/c++/4.7.1/bits/stl_uninitialized.h:77:3: required from 'static _ForwardIterator std::__uninitialized_copy<_TrivialValueTypes>::__uninit_copy(_InputIterator, _InputIterator, _ForwardIterator)
third-party/gcc-4.7.1-glibc-2.14.1/libgcc/libgcc-4.7.1/afc21dc/include/c++/4.7.1/bits/stl_uninitialized.h:119:41: required from '_ForwardIterator std::uninitialized_copy(_InputIterator, _InputIterator, _ForwardIterator)
third-party/gcc-4.7.1-glibc-2.14.1/libgcc/libgcc-4.7.1/afc21dc/include/c++/4.7.1/bits/stl_uninitialized.h:260:63: required from '_ForwardIterator std::__uninitialized_copy_a(_InputIterator, _InputIterator, _ForwardIterator, std::allocator<_Tp>&)
third-party/gcc-4.7.1-glibc-2.14.1/libgcc/libgcc-4.7.1/afc21dc/include/c++/4.7.1/bits/stl_uninitialized.h:283:67: required from '_ForwardIterator std::__uninitialized_move_if_noexcept_a(_InputIterator, _InputIterator, _ForwardIterator, _Allocator&)
third-party/gcc-4.7.1-glibc-2.14.1/libgcc/libgcc-4.7.1/afc21dc/include/c++/4.7.1/bits/vector.tcc:410:6: required from 'void std::vector<_Tp, _Alloc>::_M_emplace_back_aux(_Args&& ...)
third-party/gcc-4.7.1-glibc-2.14.1/libgcc/libgcc-4.7.1/afc21dc/include/c++/4.7.1/bits/vector.tcc:102:4: required from 'void std::vector<_Tp, _Alloc>::emplace_back(_Args&& ...)
Quelle est la raison de cette erreur et comment peut-il être résolu sans la suppression la suppression de la copie des constructeurs? Ai-je besoin d'un constructeur de déplacement - t-il besoin d'être explicitement définis?
Comment définissez-vous
J'ai touché à cette même question de moi-même, et pour moi c'était à cause de copier-élision de l'épanouissement. Le copier-ctor doit être fournie, mais n'a jamais été appelé. Je viens de tester votre mise en page, et l'expérience de la même question de montrer ici à l'aide de
Vous devez ajouter constructeur de déplacement - parce que
A(const B& b, const C& c);
?J'ai touché à cette même question de moi-même, et pour moi c'était à cause de copier-élision de l'épanouissement. Le copier-ctor doit être fournie, mais n'a jamais été appelé. Je viens de tester votre mise en page, et l'expérience de la même question de montrer ici à l'aide de
clang-500.2.79
sur mon Mac. Fournir une copie-ctor autorisé à compiler, mais jamais appelé à la mise en œuvre de copier-ctor. De même avec la fourniture d'un déménagement-ctor. Je dois dépoussiérer l'historique de la question pour trouver la question connexe. Une fois que vous avez touché un point d'extension dans le vecteur, déplacez-la construction sera invoquée si elle est disponible, de sorte que vous meilleur add-on, peu importe.Vous devez ajouter constructeur de déplacement - parce que
emplace_back
de vector
peut faire réinstallation qui nécessite de copier/déplacer constructeur. Ou simplement l'utiliser std::deque
.OriginalL'auteur vigs1990 | 2013-11-07
Vous devez vous connecter pour publier un commentaire.
Vous devez ajouter constructeur de déplacement - parce que
std::vector::emplace_back
peut faire réinstallation qui nécessite de copier/déplacer constructeur. Ou simplement l'utiliserstd::deque
.DÉMO
std::deque
ne fonctionne pas lorsque le constructeur de copie de la classe héritée de a été supprimé. Je n'ai pas accès à la source, je suis travailler avec, mais en commentant l'utilisation d'ajouter des objets de cette classe àstd::vector
etstd::deque
cesse de l'erreur,"Error C2280 'ClassName::ClassNameConstructor(const ClassName &)': attempting to reference a deleted function"
en va de Même pourstd::list
Cependant, il semble que j'ai été en mesure de contourner ce avec des pointeurs. J'ai fait un pointeur par objet, et fait d'un groupe de ces pointeurs. Pas la meilleure solution, mais je vais prendre ce qui fonctionne!
Les lecteurs sont priés de noter que le
noexcept
spécificateur de changer de constructeur et de se déplacer-l'affectation est important iciOriginalL'auteur Evgeny Panasyuk
L'erreur n'est pas la faute de emplace_back. Pour placer un objet dans un vecteur il doit être meuble ou copiable. Si vous exécutez le code avec le constructeur de copie en œuvre, vous remarquerez qu'il n'est jamais appelée. C'est une entrée sur cppreference.com
Ce que je pourrais faire pour résoudre ce problème est de mettre en œuvre le constructeur de déplacement, ce qui en fait la compilation et je ne vois pas vraiment d'inconvénient à avoir un constructeur de déplacement. Et comme avec le cctor le constructeur de déplacement ne sera pas appelée dans votre code actuel.
Je voudrais trouver un standard citation mais, parfois, cette chose vient de me donne des maux de tête
FWIW, la version la plus récente de
std::vector
documentation ne pas mentionner l'exigence que les éléments sont MoveConstructible ou MoveAssignable plus. Ils ont seulement besoin d'être Volatile.OriginalL'auteur aaronman
J'ai rencontré ce problème avec une bibliothèque externe de la classe. J'ai été faire,
"Error C2280 ClassName::ClassName(const ClassName &)': attempting to reference a deleted function"
Je devine que la classe j'ai été en utilisant avaient supprimé son constructeur de copie. Je ne pouvais pas ajouter à n'importe quel
std
conteneurs j'ai su pour mon custom dérivés de la classe des objets, qui s'est terminée leur objet avec certaines aides de la mine à l'aide d'initialisation/contrôles d'erreur.J'ai travaillé autour de ce bloqueur (risqué) pointeurs.
En gros, j'ai fait la transition vers ce:
de ce, origine:
D'intéressant à dire, c'était la première fois codage en C++ que j'ai fait nécessaire d'utiliser des pointeurs pour les non-pointeur spécifique aux exigences d'utilisation en raison d'aucune alternative. Qui me fait du souci que je manqué quelque chose de fondamental au sein de mon propre code.
Peut-être il ya une meilleure façon de le faire, mais il n'est pas sur cette question de la liste de réponses pour l'instant...
modifier pour la mise en garde:
Je devrais avoir parlé plus tôt, grâce aschepler;
si vous faites cela et le récipient que vous utilisez survit à l'objet, "bang, vous êtes mort."
Vous vous êtes. Mais bon, je suis très ouvert à d'autres options 🙂 je n'ai pas trouvé... Merci encore de me le rappeler pour ajouter l'avertissement à ma réponse.
Vous pourriez améliorer votre code en ayant un vecteur de
unique_ptr
qui vous avez créé à l'aide demake_unique
Est-ce ce que vous vouliez dire, @M. M en l'échangeant avec la ligne 3 du premier extrait?
std::unique_ptr<ClassName> name_ptr = std::make_unique<ClassName>(name);
OriginalL'auteur kayleeFrye_onDeck