Search code examples
c++move

How do I return a non-movable (but copyable) object?


Edit: End goal: I want to make a container class that never uses move, even when it's available. NonMove is a class of test objects for that container.

I tried different variations, but GCC insists on wanting to use 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();
}

Error with GCC 4.9.1 with -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;
   ^

Solution

  • End goal: I want to make a container class that never uses [move], even when it's available. NonMove is a class of test objects for that container.

    Your class does not necessarily help achieve your goal, because deleting the move constructor means the type is not CopyConstructible, so cannot be used to accurately test a container that only copies.

    To prevent moving you can ensure that all potential copies or moves are done with a const source object:

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

    The move constructor isn't viable if the RHS is const.

    It's usually sufficient to just ensure the RHS is an lvalue, as that won't be moved either, but there is a special case for function return values, which can be moved even if they are lvalues, meaning this would try to use the move constructor if it exists:

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

    Adding const ensures it will be copied instead:

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