1. Поведение std::is_move_constructible
Это ожидаемое поведение std :: is_move_constructible:
Типы без конструктора перемещения, но с конструктором копирования, который принимает const T&
аргумента, удовлетворяют std::is_move_constructible
.
Это означает, что с помощью конструктора копирования все еще возможно построить T
из ссылки rvalue T&&
. И Foo<Bar>
имеет неявно объявленный конструктор копирования.
2. Неявно объявленный конструктор перемещения Foo<Bar>
Почему компилятор создает конструктор перемещения, несмотря на то, что базовый класс не может быть сконструирован для перемещения?
Фактически, конструктор перемещения Foo<Bar>
определяется как удаленный, но обратите внимание, что удаленный неявно объявленный конструктор перемещения игнорируется разрешением перегрузки.
Неявно объявленный или заданный по умолчанию конструктор перемещения для класса T
определяется как удаленный в любом из следующих утверждений:
...
T has direct or virtual base class that cannot be moved (has deleted, inaccessible, or ambiguous move constructors);
...
Удаленный неявно объявленный конструктор перемещения игнорируется разрешением перегрузки (в противном случае это предотвратит инициализацию копирования из rvalue).
3. Различное поведение между Bar
и Foo<Bar>
Обратите внимание, что конструктор перемещения Bar
явно объявлен как deleted
, а конструктор перемещения Foo<Bar>
неявно объявлен и определен как deleted
. Дело в том, что удаленный неявно объявленный конструктор перемещения игнорируется при разрешении перегрузки, что позволяет перемещать конструкцию Foo<Bar>
с ее конструктором копирования. Но явно удаленный конструктор перемещения будет участвовать в разрешении перегрузки, это означает, что при попытке переместить конструктор Bar
будет выбран удаленный конструктор перемещения, тогда программа имеет неправильный формат.
Вот почему Foo<Bar>
можно перемещать, а Bar
- нет.
В стандарте есть четкое заявление об этом. $ 12.8 / 11 Копирование и перемещение объектов класса [class.copy]
Конструктор перемещения по умолчанию, который определен как удаленный, игнорируется разрешением перегрузки ([over.match], [over.over]). [Примечание: удаленный конструктор перемещения в противном случае помешал бы инициализации из rvalue, который вместо этого может использовать конструктор копирования. - конец примечания]
person
songyuanyao
schedule
25.08.2016
class FamousPaintingInTheLouvre
? - person einpoklum   schedule 25.08.2016char *
является конструктивным перемещением. - person David Schwartz   schedule 25.08.2016