2016-10-14 6 views
1

Je comprends que le code suivant ne compile pas puisque le constructeur de déplacement de A est supprimé car le mutex n'est pas mobile.Insertion d'un objet ayant un champ non-copiable dans un vecteur std ::

class A { 
    public: 
    A(int i) {} 

    private: 
    std::mutex m; 

}; 


int main() {  
    std::vector<A> v; 
    v.emplace_back(2); 
} 

Mais si je veux que mon A à stocker dans un récipient std comment dois-je aller à ce sujet? Je vais bien avec A étant construit "à l'intérieur" du conteneur.

+0

Un objet qui n'est pas copiable ou déplaçable ne peut simplement pas être dans un 'std :: vector'. Pensez-y: si le vecteur est redimensionné et doit être réaffecté, ses éléments doivent être copiés ou déplacés. Un conteneur qui fonctionne est 'std :: list'. – zindorsky

+0

http://stackoverflow.com/a/29988626/560648 peut être d'un certain intérêt –

+0

Je suis confus pourquoi je peux utiliser l'opérateur d'index dans un std :: carte sans problème: class A { public: void foo() {}; privé: std :: mutex m; }; int main() { std :: carte m; m [0] .foo(); } – user695652

Répondre

3

std::vector::emplace_back peut avoir besoin de développer la capacité d'un vecteur. Puisque tous les éléments d'un vecteur sont contigus, cela signifie déplacer tous les éléments existants vers le nouveau stockage alloué. Ainsi, le code implémentant emplace_back doit appeler le constructeur de mouvement en général (même si pour votre cas avec un vecteur vide, il l'appelle zéro fois).

Vous n'obtiendriez pas cette erreur si vous utilisiez, par exemple, std::list<A>.