1

I have objects that holds pointers and shares them with others. Moving them is fine, but copying not. I would like to store them in vectors and maps. The following code works only when A has no destructor. However I would need a destructor to clean up my pointers.

#include <vector>

struct OnlyMove
{
    OnlyMove(const OnlyMove&) = delete;
    OnlyMove& operator=(const OnlyMove&) = delete;
    OnlyMove(OnlyMove&&) = default;
    OnlyMove& operator=(OnlyMove&&) = default;

protected:
    OnlyMove() = default;
};

struct A : OnlyMove
{
    A(int){}
    ~A(){} // makes compilation fail
};

int main()
{
    std::vector<A> y;
    y.emplace_back(1);
}

The error when I have a destructor:

/usr/local/include/c++/8.2.0/bits/stl_construct.h: In instantiation of 'void std::_Construct(_T1*, _Args&& ...) [with _T1 = A; _Args = {A}]': … error: use of deleted function 'OnlyMove::OnlyMove(const OnlyMove&)'

I don't understand why. What role does the destructor play here?

Live Demo

ypnos
  • 50,202
  • 14
  • 95
  • 141

1 Answers1

3

You need:

struct A : OnlyMove
{
    A(int){}
    A(A&&) = default;  // need this
    ~A() {} 
}; 

When you introduce the desctructor, the move constructor disappears. Without the move constructor or a copy constructor, it can't be placed in a vector.

EDIT: the move constructor is best if it is noexcept, otherwise std::vector::resize and std::vector::push_back have no guarantees when exceptions are thrown.

Michael Veksler
  • 8,217
  • 1
  • 20
  • 33
  • Thank you, I tried it but had other problems in my code, and in the example code I didn't think about it anymore. – ypnos Feb 20 '19 at 14:19
  • I also realized that I can save myself all the trouble by using unique_ptrs. – ypnos Feb 20 '19 at 15:22
  • @ypnos that will also work, since unique_ptrs are already movable. Note however, that if this is performance critical code, then the extra memory management might affect performance – Michael Veksler Feb 20 '19 at 15:35