
Peter Dimov wrote:
How would such a copy behave regarding connect() and disconnect()? Neither should affect the original signal, so this would be either a deep copy or an implementation with copy on write semantics.
A shared signal is mostly equivalent to the current noncopyable signal, except that it's less inconvenient and less unsafe. Currently you are forced to use references or pointers to the signal, and every entity that posesses such a reference can connect() and disconnect(). A shared_ptr
reformulation has the same effect, minus the possibility of a dangling reference.
A signal would then rather be a handle object, or not? I wouldn't see a problem in this if it were just for the invocation and connection to another signal, but with member functions like connect() and disconnect() it would appear like a rather unusual construct to me.
The next step is to have a shallow slot (shared_ptr
) but a one level deep copy in the signal (vector<slot>). In this case connects and disconnects will only affect the copy, although the sharing at the SlotFunction level may still be undesirable at times. Immutable SlotFunctions would handle sharing (and concurrent calls) fine, of course; only stateful function objects will have a problem. A fully deep copy (vector< function<> >) avoids any sharing, but makes the signal quite expensive to copy.
When the user provided a reference to a function object for the slot construction, the deep copy will still not give you a function with its own state. Together with connects and disconnects being only effective on one copy, this can become quite messy. What happens to the connection objects returned by connect()? Do they only refer to the original slot or also to every copy?
I already don't like the fact that there is no distinction between control over connections and control over invocation. Every entity that is allowed to connect to a signal can also emit it, unless you provide a separate connect() yourself and hide the actual signal.
Is this a problem in practice?
No, not really. I was only reminded of this by the idea of copyable signals. It would be easy to split a signal into a connection managing base and invocable subclass, so that the owner could just expose a reference to the base for observers to connect to. I couldn't come up with a proper name for that base class right now, though. Regards Timmo Stange