Bonjour à tous,
J'ai un petit problème avec la sémantique de déplacement émulée par boost::move (le sandbox, download). Les objets de mon projet ont tous un identifiant et un nom, vu que mes objets ont une sémantique d'entité, ils ressemblent à ça:
C'est pratique et ça évite des erreurs. Maintenant je voudrais utiliser la sémantique de déplacement pour stocker ces objets dans une collection, j'ai donc défini un constructeur par déplacement:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 class UnObjet : private boost::noncopyable { public: UnObjet(std::string const& _name, size_t const _id) : name(_name), id(_id) {} std::string const name; size_t const id; };
Jusque là, tout va bien, mon problème c'est que si maintenant j'essaie de déplacer le vecteur que je viens de construire, le compilateur m'indique qu'il me faudrait l'opérateur "move assign" (affectation par déplacement?) et là, c'est le drame puisque du fait de mes membres const, je ne peux pas définir un opérateur "move assign".
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 class UnObjet : private boost::noncopyable { private: BOOST_MOVABLE_BUT_NOT_COPYABLE(UnObjet) public: UnObjet(std::string const& _name, size_t const _id) : name(_name), id(_id) {} UnObjet(BOOST_RV_REF(UnObjet) o) : name(boost::move(o.name)), id(boost::move(o.id)) {} std::string const name; size_t const id; }; int main(void) { using namespace boost::container; vector<UnObjet> v; UnObjet o0 (0, "zero"); UnObjet o1 (1, "un"); v.push_back(boost::move(o0)); v.push_back(boost::move(o1)); assert(v.size() == 2); return 0; }
(Le compilateur me jette avec: l-value définit un objet const)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 UnObjet& operator=(BOOST_RV_REF(UnObjet) o) { id = boost::move(o.id); return *this; }
J'ai actuellement deux pistes pour trouver une solution:
(1) ne plus utiliser de vecteur mais des listes
(2) virer mes const, mettre mes attributs en privé et faire des accesseurs (et donc je pourrais alors définir mon move assign)
Que pensez-vous de ces solutions? Avez vous des infos sur les prérequis des conteneurs move-aware (constructible par défaut, déplaçables par copie, déplaçables par affectation, ...)?
Edit: Je viens de faire un test, une dernière possibilité est de passer par des const_cast dans l'opérateur d'affectation par déplacement:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 UnObjet& operator=(BOOST_RV_REF(UnObjet) o) { const_cast<size_t&>(id) = boost::move(o.id); const_cast<std::string&>(name) = boost::move(o.name); return *this; }
Partager