6

Is there a way use STL containters with non-copyable elements?

something like this:

class noncopyable
{
    noncopyable(noncopyable&);
    const noncopyable& operator=(noncopyable&);
public:
    noncopyable(){};
};

int main()
{
    list<noncopyable> MyList; //error C2248: 'noncopyable::noncopyable' : cannot access private member declared in class 'noncopyable'
}
Vargas
  • 2,125
  • 2
  • 33
  • 53

3 Answers3

16

No, non-copyable elements can't be in C++ container classes.

According to the standard, 23.1 paragraph 3, "The type of objects stored in these components must met the requirements of CopyConstructible types (20.1.3), and the additional requirements of Assignable types."

David Thornley
  • 56,304
  • 9
  • 91
  • 158
  • Good point! std::unique_ptr could be an option for him if he uses a rather new compiler with the new C++ STL. – jdehaan Sep 17 '09 at 18:06
  • I had to solve my problem by removing the complex deep copy need of the object. I've selected this answer because it answers my question directly. But the other one is good too! – Vargas Sep 17 '09 at 20:04
  • 1
    If these are the requirements, why is it possible to store a unique_ptr in a vector or list? unique_ptr is not copy-constructible. – Mark Vincze Aug 13 '14 at 14:10
  • Note: when move semantics were introduced in C++11, this became possible. See https://stackoverflow.com/a/26906231 – ahiijny Sep 26 '18 at 21:13
15

One option is to create a list of pointers to the elements (preferrably a shared_ptr). This is not exactly what you want but it will get the job done.

JaredPar
  • 733,204
  • 149
  • 1,241
  • 1,454
  • 2
    +1, more or less the only option, since IIRC `std::list` requires elements to be copy-constructible. – Michael Krelin - hacker Sep 17 '09 at 17:46
  • That's exactly what I'm trying to avoid, I want to call MyList.clear() sometimes and I need that the destructor for noncopyable to be called. – Vargas Sep 17 '09 at 17:47
  • Yup - the standard says: "The type of objects stored in these components must meet the requirements of CopyConstructible types (20.1.3), and the additional requirements of Assignable types." – Michael Burr Sep 17 '09 at 17:48
  • 1
    @Vargas - it seems as though `shared_ptr<>` will do what you want. – Michael Burr Sep 17 '09 at 17:49
  • 1
    All containers require that contained types are copyable. A shared_ptr would automate memory management, so that you can call clear() to your heart's content. – UncleBens Sep 17 '09 at 17:49
2

Another option is to use the Boost Pointer Container library. This acts much like a standard container of std::auto_ptrs would, were such a thing possible: it retains exclusive ownership of its elements, and it cannot be copied. It also has less overhead than a standard container of shared_ptrs.

Alice Purcell
  • 12,622
  • 6
  • 51
  • 57