choeger choeger - 1 month ago 9x
C++ Question

Why not to copy a class consisting of a single shared_ptr

Recently, I read an article about lazy data structures in C++ (this question is not about lazy, or the particular data structure, though - it is just the motivation).

A lazy stream (list) is implemented as follows:

template<class T>
class Stream
std::shared_ptr <Susp<Cell<T>>> _lazyCell;
Stream() {}
Stream(std::function<Cell<T>()> f)
: _lazyCell(std::make_shared<Susp<Cell<T>>>(f))
Stream(Stream && stm)
: _lazyCell(std::move(stm._lazyCell))
Stream & operator=(Stream && stm)
_lazyCell = std::move(stm._lazyCell);
return *this;
bool isEmpty() const
return !_lazyCell;
T get() const
return _lazyCell->get().val();
Stream<T> pop_front() const
return _lazyCell->get().pop_front();

The author mentions the move constructor:

I also added a move constructor and a move assignment operator for efficiency.

However, due to the explicit presence, one cannot simply assign a
. What is the motivation behind this?

As far as I can tell, the class consists solely of a
, which can be trivially copied. Is there any benefit in forbidding copy-construction in such a class?


The shared_ptr is used internally to share lazy value cells as part of the private implementation.

However, from the user's point of view, it's an immutable object. Providing a copy constructor and assignment operator would undo this immutability.

He is modelling Haskell's immutable object's behaviour.

If it were thread-safe to do so, it would be reasonable to make this object copyable since in reality it's a handle to an (albeit more complex than usual) shared impl.

However, copyers would need to understand that they were copying a handle to shared state, and not state itself.