Вызвать ошибку времени компиляции, если std :: move приведет к непреднамеренной копии?

В своем выступлении на GoingNative 2013 Скотт Мейерс отметил, чтоstd::move нет никакой гарантии, что сгенерированный код действительно выполнит перемещение.

Пример:

void foo(std::string x, const std::string y) {
  std::string x2 = std::move(x); // OK, will be moved
  std::string y2 = std::move(y); // compiles, but will be copied
}

Здесь конструктор перемещения не может быть применен, но из-за разрешения перегрузки будет использоваться обычный конструктор копирования. Этот запасной вариант может иметь решающее значение для обратной совместимости с кодом C ++ 98, но в приведенном выше примере это, скорее всего, не то, что задумал программист.

Есть ли способ заставить конструктор перемещения вызываться?

Например, предположим, что вы хотите переместить огромную матрицу. Если ваше приложение действительно зависит от перемещаемой матрицы, было бы здорово сразу же получить ошибку компиляции, если перемещение невозможно. (В противном случае проблема с производительностью может легко пройти через модульные тесты, и вы обнаружите это только после некоторого профилирования.)

Давайте назовем этот гарантированный ходstrict_move, Я хотел бы иметь возможность писать такой код:

void bar(Matrix x, const Matrix y) {
  Matrix x2 = strict_move(x); // OK
  Matrix y2 = strict_move(y); // compile error
}

Является ли это возможным?

Редактировать:

Спасибо за отличные ответы! Были некоторые законные просьбы прояснить мой вопрос:

Долженstrict_move потерпеть неудачу, если вход const?Долженstrict_move потерпеть неудачу, если результат не приведет к фактической операции перемещения (даже если копия может быть такой же быстрой, как перемещение, например,const complex)?И то и другое?

Моя первоначальная идея была очень расплывчатой: я считал примеры Скотта Мейерса весьма тревожными, поэтому я подумал, можно ли заставить компилятор предотвращать такие непреднамеренные копии.

Скотт Мейерс упомянул в своем выступлении, что общее предупреждение компилятора не вариант, так как это приведет к огромному количеству ложных срабатываний. Вместо этого я хочу сообщить компилятору что-то вроде «я»m 100% уверен, что это всегда должно приводить к операции перемещения, а копия слишком дорогая для этого конкретного типа ".

Таким образом, я бы бесцеремонно сказал, чтоstrict_move должен потерпеть неудачу в обоих случаях. Тем временем яЯ не уверен, что будет лучше. Другие аспекты, которые я не сделалне считаю это.noexcept

С моей стороны, точная семантикаstrict_move открыты. Все, что помогает предотвратить некоторые глупые ошибки во время компиляции без серьезных недостатков, прекрасно.

Ответы на вопрос(3)

Ваш ответ на вопрос