2

I am trying to insert a moveable, non-copyable object into std::vector. I reduced the original code to this example:

#include <vector>
class MovingClass
{
public:
  MovingClass(const int value) : _value(new int(value)) {}
  //! No copy allowed
  MovingClass(const MovingClass& src) = delete;
  MovingClass& operator=(const MovingClass& src) = delete;
  // move is OK
  MovingClass(MovingClass&& source) : _value(source._value) { source._value = nullptr; }
  MovingClass& operator=(MovingClass&& source) { _value = source._value; source._value = nullptr; }

  ~MovingClass() { delete _value; }
  // do not mind that this is all kinds of bad, it's just an example
  int* _value;
};

int test_vector_main()
{
  std::vector<MovingClass> containers;
  containers.push_back({ 42 });

  return 0;
}

The original purpose of the class is closing winapi handles, not deleting pointers.

I can reproduce the warning in a blank project if I set "Enable C++ Exceptions" to "No" in Configuration Properties->C/C++->All Options.

The project I work with treats warnings as errors and has exceptions disabled.

I am not sure what to do except giving up on no-copy rules or enabling the exceptions. I'll enable the exceptions, but if I couldn't what else could I do?

Why does push_back even require exceptions?

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
Tomáš Zato
  • 50,171
  • 52
  • 268
  • 778
  • 3
    Does marking your move constructor `noexcept` help? – SergeyA Sep 11 '19 at 14:32
  • Which version of the Visual C++ compiler are you using? – Ben Voigt Sep 11 '19 at 14:36
  • 1
    @Tomáš Zato The move-assignment operator has no return expression. – Vlad from Moscow Sep 11 '19 at 14:37
  • 1
    From what I understand, compiling without exceptions doesn't remove exception related code from the standard library. The preprocessor definition `_HAS_EXCEPTIONS` seems to be used to strip out that code. Without it, you have `throw/try/catch` in the standard library that doesn't work, which is what the warning is trying to say. – François Andrieux Sep 11 '19 at 14:50

1 Answers1

3

Why does push_back even require exceptions?

vector::push_back has to do two things:

  • Make sure that there's space for the new element. That could involve allocating memory - which can fail. It reports this failure by throwing an exception.
  • Construct a new element in the vector. That involves calling your class' copy or move constructor - which can fail. Constructors usually report failures by throwing an exception.

You can indicate that your move constructor will never fail by marking it as noexcept.

Marshall Clow
  • 15,972
  • 2
  • 29
  • 45