Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

c++

move

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;
   ^
like image 823
Thomas Avatar asked Sep 04 '14 10:09

Thomas


People also ask

How do I make my class non copyable?

class NonCopyable { public: NonCopyable (const NonCopyable &) = delete; NonCopyable & operator = (const NonCopyable &) = delete; protected: NonCopyable () = default; ~NonCopyable () = default; /// Protected non-virtual destructor }; class CantCopy : private NonCopyable {};

What is boost NonCopyable?

Boost::noncopyable prevents the classes methods from accidentally using the private copy constructor. Less code with boost::noncopyable.


1 Answers

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);
}
like image 97
Jonathan Wakely Avatar answered Oct 27 '22 01:10

Jonathan Wakely