Home > OS >  Which STD container to use to get [] operator and erase elements without moving memory around?
Which STD container to use to get [] operator and erase elements without moving memory around?

Time:07-28

I used std::vector<MyClass> and everything was fine until I had to use erase() function. Problem caused by MyClass having

MyClass(const MyClass&) = delete;
MyClass& operator=(const MyClass&) = delete;

This is needed because MyClass holds unique_ptr objects and I generally want to avoid copy. But at this point my code has index access [] operator utilized, and I dont want to re write chucks of code. Is there a container in STD that is suitable?

Edit:

To people suggesting usage of move constructor, I've tried this:

//MyClass(const MyClass&) = delete;
//MyClass& operator=(const MyClass&) = delete;
MyClass(MyClass&&) = default;

but compiler(g ) still gives error:

/usr/include/c  /11/bits/stl_algobase.h:405:25: error: use of deleted function ‘M::MyClass& M::MyClass::operator=(const M::MyClass&)’
  405 |               *__result = std::move(*__first);
      |               ~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~

saying:

note: ‘M::MyClass& M::MyClass::operator=(const M::MyClass&)’ is implicitly declared as deleted because ‘M::MyClass’ declares a move constructor or move assignment operator

or I should not use default keyword and actually define move constructor?

CodePudding user response:

As std::unique_ptr<T> is a moveable and non-copyable type, any class with a std::unique_ptr<T> member will by default be moveable and non-copyable (as long as all of the other members are at least moveable).

#include <memory>
#include <utility>

struct A {
    std::unique_ptr<int> ptr;
};

int main()
{
    A a;
    //A b = a; //Will not compile
    A c = std::move(a); // Perfectly legal
}

Therefore if you remove the copy contstructor, copy assignment operator, move constructor, and move assignment operator, then everything would work fine. Your type would not be copyable, and erasing from std::vector would work fine.

Note: std::vector<T>::operator[] returns a reference to the element so no copy is performed at this step either (for T not equal to bool).

If you want to explicitly = delete the copy semantics then you also have to = default both the move constructor and move assignment operator to keep the move semantics of the type. This is known as the rule of 5.

  • Related