Non-copyable elements in vector

11,746

Solution 1

Yes you can have std::vector<NotCopyable> if NotCopyable is movable:

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

    NotCopyable(NotCopyable&&) = default;
    NotCopyable& operator = (NotCopyable&&) = default;
};

int main()
{
    std::vector<NotCopyable> v;
    NotCopyable nc;

    v.push_back(NotCopyable{});
    v.emplace_back();
    v.push_back(std::move(nc));
}

Live example.

Solution 2

As long as the elements are movable then, yes, simply store them in the vector.

Share:
11,746

Related videos on Youtube

Lieuwe
Author by

Lieuwe

Updated on September 15, 2022

Comments

  • Lieuwe
    Lieuwe over 1 year

    I have a non-copyable class (i.e. the copy constructor & assignment operator are marked as 'delete'). I would like to keep these in a std::vector.

    It is a RAII class so simply storing the pointer or reference to it is not what I am looking for.

    My knowledge of the new initialiser lists & move constructors is somewhat limited, is this possible?

    • Jarod42
      Jarod42 over 9 years
      Is the class movable ?
    • Lightness Races in Orbit
      Lightness Races in Orbit over 9 years
      @rockoder: Refer to!
    • Lieuwe
      Lieuwe over 9 years
      Seems the problem was that my class was in fact not movable. I didn't realise that specifying a copy constructor (and assignment operator) means that the compiler doesn't implicitly declare a move constructor. I'll accept jarod's answer below as that example works perfectly. Thanks
  • JBL
    JBL over 9 years
    Does push_back() actually works on such non-copyable but movable object without explicit std::move?
  • Lieuwe
    Lieuwe over 9 years
    How? If I do something like vec.push_back(myClass()) or vec.push_back(std::move(my_class())) it still complains that the copy constructor & assignment operator are deleted.
  • Lightness Races in Orbit
    Lightness Races in Orbit over 9 years
    @Lieuwe: It shouldn't. What is "it"? What compiler?
  • JBL
    JBL over 9 years
    @Lieuwe In this case, you should rather use emplace_back() if you want to create it in the vector rather than storing an already existing entity.
  • Lightness Races in Orbit
    Lightness Races in Orbit over 9 years
    @JBL: If it's a temporary, yeah. But that's going into the realm of "how do I move objects", which is not this question.
  • M.M
    M.M over 9 years
    You should probably expand on this answer a bit in order to avoid downvotes (e.g. how should members be inserted and removed ; are there any other constraints on which vector member functions can be used (e.g. resize))
  • Lieuwe
    Lieuwe over 9 years
    @LRO - it seems my class was in fact not movable as the compiler didn't implicitly declare a move constructor in my case.
  • Lightness Races in Orbit
    Lightness Races in Orbit over 9 years
    @Matt: This is not the place for a blow-by-blow tutorial on how to store objects of movable types in vectors. The OP has C++ books for that. There's no evidence given in the question that he didn't actually tried to simply do the thing so this is as far as I go! Beyond that we enter the territory of certain duplicates.
  • Lightness Races in Orbit
    Lightness Races in Orbit over 9 years
    @Lieuwe: So, it's all been a red herring!
  • Markus Mayer
    Markus Mayer over 9 years
    If you want push_back to work correctly (offer the strong exception garantie) you have to declare the move(+ move-Assignment) functions as noexcept.
  • T.C.
    T.C. over 9 years
    @MarkusMayer Not really. If they aren't declared noexcept and the class is also copyable, push_back will copy to provide the strong exception safety guarantee. But if it's not copyable, then as long as the move functions don't actually throw, you are safe.
  • Ciro Santilli OurBigBook.com
    Ciro Santilli OurBigBook.com over 3 years
    Non-copyable non-movable case: stackoverflow.com/questions/39770824/…