Why are signals and slots better than plain old callbacks?

Why are signals and slots better than plain old callbacks?

Because signals are a lot like plain old callbacks, on top of having extra features and being deeply integrated with Qt APIs. It ain't rocket science - callbacks + extra features + deep integration is greater than callbacks alone. C++ might be finally offering a cleaner way to do callbacks, but that doesn't replace Qt signals and slots, much less render them obsolete.

The slot aspect got a little less relevant since Qt 5, which allowed signals to be connected to any functions. But still, slots integrate with the Qt meta system, which is used by a lot of Qt APIs to get things working.

Yes, you could use callbacks for pretty much everything which signals are supposed to achieve. But it is not easier, it is a little more verbose, it doesn't automatically handle queued connections, it won't integrate with Qt the way signals do, you could probably work around that as well, but it will get even more verbose.

And in the case of QML, which nowadays is the primary focus of Qt, you are essentially stuck with Qt's signals. So I presume signals are here to stay.

Signals and slots are "better" because Qt is conceptually built around them, they are part of the API and are used by a lot of the APIs. Those concepts have been in Qt for a long time, from back in the days C++ didn't offer much callback support aside from plain old function pointers it inherited from C. This is also the reason Qt cannot simply switch to std callbacks - it will break a lot of stuff and is a needless effort. The same reason Qt continues to use those evil unsafe plain old pointers instead of smart pointers. Signals and slots are not obsolete as a concept, even less so technically when using Qt. C++ simply got too late in the game. It is unrealistic to expect that everyone will now rush into moving away from their own implementations in their giant code bases now that C++ finally provides alternatives as part of the language standard library.


In general: Signals and Slots differs from callbacks by the fact that it decouples the call (Signal) from the Handler (Slot). Which means: you can register your slot to be on a different thread, you can listen to one signal from many slots and change queuing strategy easily. but it has its costs(In QT world at least...): string evaluation and generally more internal work / code branches.. in short, it's an higher level concept.

that being said, you can do all of those with simple callbacks, but it will be like reinventing the wheel.


There's one enormous difference between the two: threads.

Traditional callbacks are always called in the context of the calling thread. Not so with signals and slots -- as long as the thread is running an event loop (as it will be if it's a QThread) the slot can be in any thread.

Sure, you can do all of this manually with a callback -- I've written many Win32 apps over the years that use Windows-style message pumps that juggle callbacks across threads -- but it's a lot of boilerplate code and not much fun to write, maintain, or debug.