Как вернуть недвижущийся (но скопируемый) объект?

Изменить: Конечная цель: Я хочу создать класс контейнера, который никогда не использует перемещение, даже если он доступен. NonMove - это класс тестовых объектов для этого контейнера.

Я пробовал разные варианты, но GCC настаивает на желании использовать move.

class NonMove {
 public:
  NonMove() {}

  // Copy.
  NonMove(const NonMove&) {}
  NonMove& operator=(const NonMove&) {}

  // Move
  NonMove(NonMove&&) = delete;
  NonMove& operator=(NonMove&&) = delete;
};

NonMove foo() {
  return NonMove();
}

Ошибка с GCC 4.9.1 с -std = gnu ++ 11

move.cc: In function ‘NonMove foo()’:
move.cc:15:18: error: use of deleted function ‘NonMove::NonMove(NonMove&&)’
   return NonMove();
                  ^
move.cc:10:3: note: declared here
   NonMove(NonMove&&) = delete;
   ^

Ответы

Ответ 1

Конечная цель: я хочу создать класс контейнера, который никогда не использует [move], даже если он доступен. NonMove - это класс тестовых объектов для этого контейнера.

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

Чтобы предотвратить перемещение, вы можете гарантировать, что все потенциальные копии или перемещения выполняются с помощью источника-источника const:

NonMove foo() {
  return const_cast<const NonMove&&>(NonMove());
}

Конструктор перемещения не является жизнеспособным, если RHS const.

Обычно достаточно просто убедиться, что RHS является значением lvalue, поскольку это тоже не будет перемещено, но есть специальный случай для возвращаемых значений функции, которые могут перемещаться, даже если они являются lvalues, что означает, что это попытается используйте конструктор перемещения, если он существует:

NonMove foo() {
  NonMove nm;
  return nm;
}

Добавление const гарантирует, что оно будет скопировано:

NonMove foo() {
  NonMove nm;
  return const_cast<const NonMove&>(nm);
}