What's an example of a situation where callbacks work better than signals-and-slots for you? My simple-minded understanding of signals is that they are collections of callbacks...
I kinda view signals as a more generalized and powerful form of callbacks, but sometimes overkill.
If I just want to run an function on every element of a container, passing in a callback (or functor) works perfectly. With signals and slots (in C++ specifically), both the container and the caller would have to support signals and slots, I'd have to attach a slot "DoSomethingToElement()" to the container's signal - which would be a weird signal, not really even an event - maybe called "OnElementAccessed" or something oddly forced sounding like that - and then call the container's "Crawl()" function so the signals get sent. It'd make much more sense to just pass a callback into the Crawl() function directly (and to rename the Crawl() function to something better suited like ForEvery()).
Callbacks are useful because they can be temporary or permanent (like signals and slots) but if they are temporary they don't require as much setup, and they don't require the caller to support slots.
Callback:
object.doSomething(onCallback);
Signals and slots: (when used for a temporary purpose)
object.attach(this, onCallback);
object.doSomethingThatSignals();
object.dettach(this, onCallback);
Signals and slots are more powerful and more flexible, but aren't always the best choice for me.
One of their pros is having multiple slots from multiple objects attached to the same signal, and another is the ease of use when an object has many signals that it emits.
It depends on the needs of the code. My logging system just takes a callback pointer that it permanently holds onto, to process log messages when they arrive. However, it might be good to expand it to take any number of functor objects, so I can have the logs outputted to multiple locations. That's a step inbetween callbacks and signals and slots.
I think my game objects will end up using alot of signals and slots (but that's still unknown to me), because they have alot of different types of interactions between each other and are in a parent-child hierarchy.
And my GUI stuff (since I'm using Qt) uses loads of signals and slots to great benefit - with a variety of different types of interactions and data being communicated. The signals going up to the parents and siblings, and regular function calls going down to the children.
Both the GUI (currently) and my game objects (in the future) also use regular event message queues - these are messages from the overall system rather than communication between two specific objects.
</inexperienced> </still-discovering-what-works>