Le constructeur de copie est requise par vector
afin qu'il puisse copier l'élément quand il a besoin de développer son stockage.
Vous pouvez lire le document pour vector
T doivent satisfaire aux exigences de CopyAssignable et CopyConstructible. (jusqu'à C++ 11)
Les exigences qui sont imposées aux éléments dépendent des opérations réelles effectuées sur le conteneur . Généralement, il est requis que le type d'élément soit un type complet et qu'il réponde aux exigences de Effaçable, mais de nombreuses fonctions membres imposent des exigences plus strictes. (Puisque C de 11) (jusqu'à ce que C++ 17)
Les exigences qui sont imposées sur les éléments dépendent des opérations effectuées réelles sur le récipient. Généralement, il est nécessaire que le type d'élément soit conforme aux exigences de Effaçable, mais de nombreuses fonctions membres imposent des exigences plus strictes. Ce conteneur (mais pas ses membres ) peut être instancié avec un type d'élément incomplet si l'allocateur satisfait aux exigences d'exhaustivité de l'allocateur.
Certains exploitation forestière peut vous aider à comprendre ce qui se passe
For this code
class MyClass
{
public:
typedef enum
{
e1 = 1,
e2 = 2,
e3 = 3,
} Type;
private:
Type _type;
public:
MyClass(Type type): _type(type) { std::cout << "create " << type << "\n"; };
MyClass(const MyClass& other) { std::cout << "copy " << other._type << "\n"; }
};
int main() {
std::vector<MyClass> list;
list.reserve(2);
list.emplace_back(MyClass::e1);
list.emplace_back(MyClass::e2);
list.emplace_back(MyClass::e3);
}
La sortie est
create 1
create 2
create 3
copy 1
copy 2
Vous pouvez donc emplace_back
n'utilise le constructeur souhaité pour créer l'élément et appelez le constructeur de copie quand il a besoin d'augmenter le stockage. Vous pouvez appeler reserve
avec suffisamment de capacité à l'avance pour éviter d'avoir à appeler le constructeur de copie.
Si pour une raison quelconque, vous ne voulez vraiment pas à copier constructible, vous pouvez utiliser std::list
au lieu de std::vector
comme list
est mis en œuvre en tant que liste chaînée, il n'a pas besoin de déplacer les éléments.
http://coliru.stacked-crooked.com/a/16f93cfc6b2fc73c
Pour résoudre le problème, ajoutez un constructeur de déplacement par défaut. Si vous ne voulez pas non plus, vos options sont plus limitées –
Merci, j'ai choisi d'écrire un constructeur de mouvement. – wqyfavor