En http://en.cppreference.com/w/cpp/memory/polymorphic_allocator :
polymorphic_allocator
ne se propage pas lors d'une affectation de copie de conteneur, d'une affectation de déplacement ou d'un échange. Par conséquent, l'affectation de déplacement d'unpolymorphic_allocator
-utilisation d'un conteneur peut jeter, et l'échange de deuxpolymorphic_allocator
-L'utilisation de conteneurs dont les allocateurs ne se comparent pas de manière égale entraîne un comportement non défini.
Pourquoi voudrais-je avoir ce comportement ? Non seulement cela semble introduire un comportement indéfini gratuit sur le swap, mais plus important encore pour mes objectifs, cela implique que std::pmr::vector
est effectivement un type non assignable par le mouvement. Je veux dire, il est assignable par le mouvement, mais c'est presque garanti d'être inefficace.
std::vector<int> v = {1, 2, 3};
std::vector<int> w;
w = std::move(v); // nocopy, nothrow
std::pmr::monotonic_buffer_resource mr(1000);
std::pmr::vector<int> v( {1, 2, 3}, &mr );
std::pmr::vector<int> w;
w = std::move(v); // yescopy, yesthrow
Je pense qu'il s'agit d'une tentative primitive de régler les problèmes de propriété. Dans mon deuxième exemple ci-dessus, v
contient une référence à mr
mais v
n'a pas réellement propre mr
. Permettre aux références non propriétaires de se propager sans contrôle dans tout le système aurait tendance à introduire de nombreux bogues subtils. Ainsi, plutôt que d'inventer un posséder les concepteurs ont décidé de simplement ne pas propager la référence à mr
. Cela a fini par avoir de mauvais effets, comme le fait que le déplacement d'un vecteur copie maintenant ses données ; mais vous ne vous retrouvez pas avec autant de pointeurs pendants vers des ressources mémoire. ( Quelques Oui, mais pas autant .)
P.S. Je vois déjà que vous pouvez éviter le copier/jeter en configurant l'allocateur à l'avance, comme ceci :
std::pmr::monotonic_buffer_resource mr(1000);
std::pmr::vector<int> v( {1, 2, 3}, &mr );
std::pmr::vector<int> w(v.get_allocator());
w = std::move(v); // nocopy, nothrow