1. Le comportement de l' std::is_move_constructible
Ce comportement est attendu de std::is_move_constructible:
Sans un constructeur de déplacement, mais avec un constructeur de copie qui accepte const T&
arguments, satisfaire std::is_move_constructible
.
Ce qui signifie avec un constructeur de copie, il est toujours possible de construire T
de référence rvalue T&&
. Et Foo<Bar>
a Implicitement déclaré constructeur de copie.
2. La implicitement déclarées constructeur de déplacement de l' Foo<Bar>
Pourquoi ne compilateur génère constructeur de déplacement en dépit de la classe de base non-déplacer constructible?
En fait, le constructeur de déplacement de l' Foo<Bar>
est défini comme étant supprimés, mais notez que l'supprimé implicitement déclarées constructeur de déplacement est ignoré par la résolution de surcharge.
La implicitement déclarées ou défaut constructeur de déplacement pour la classe T
est
définie comme supprimé dans une des conditions suivantes est remplie:
...
T has direct or virtual base class that cannot be moved (has deleted, inaccessible, or ambiguous move constructors);
...
L'supprimé implicitement déclarées constructeur de déplacement est ignoré par la résolution de surcharge (sinon il serait d'empêcher la copie de l'initialisation de rvalue).
3. La différence de comportement entre Bar
et Foo<Bar>
Notez que le constructeur de déplacement de l' Bar
est déclaré en tant que deleted
explicitement, et le constructeur de déplacement de l' Foo<Bar>
est implicitement déclarée et définie en tant que deleted
. Le point est que l'supprimé implicitement déclarées constructeur de déplacement est ignoré par la résolution de surcharge, ce qui permet de se déplacer en construire Foo<Bar>
avec son constructeur de copie. Mais la suppression explicite déplacer constructeur de participer à la résolution de surcharge, signifie que lorsque vous essayez de déplacer constructeur Bar
supprimés constructeur de déplacement sera sélectionné, alors le programme est mal formé.
C'est pourquoi, Foo<Bar>
est constructible mais Bar
ne l'est pas.
Le standard a une déclaration explicite à ce sujet. $12.8/11 la Copie et le déplacement des objets de la classe
[classe.copier]
Un défaut constructeur de déplacement qui est défini comme étant supprimés est ignoré par la résolution de surcharge ([- dessus.match], [- dessus.plus]). [ Remarque: la suppression du constructeur de déplacement serait interférer avec initialisation à partir d'une rvalue qui peut utiliser le constructeur de copie à la place. - la note de fin ]