Короче говоря: каждый именованный объект Lvalue , и даже если v
является ссылкой на Rvalue, вам нужно использовать move
, чтобы заставить вызывать move ctor.
Из справочно-значимых категорий
Даже если тип переменной является rvalue ссылкой, выражение
состоящее из его имени выражение lvalue ;
теперь ваш элемент данных m_v
является вектором, который содержит конструктор копирования и перемещения.
Следующие предложения описывают, какой из них называется, reference :
Если предусмотрены конструкторы копирования и перемещения, а другие нет
конструкторы жизнеспособны, разрешение перегрузки выбирает ход
конструктор, если аргумент является rvalue того же типа (xvalue
такой как результат std :: move или prvalue, такой как безымянный
временно (до C ++ 17)) и выбирает конструктор копирования, если
аргумент - это lvalue (именованный объект или функция / оператор, возвращающий
lvalue ссылка ).
Итак, когда вы пишете:
m_v(std::move(v)) // move ctor is called because you are passing Xvalue
но в этом:
m_v(v) // copy ctor is called because v as named object is passed