Callback vs callable object vs function

Aug 2, 2023 at 5:04pm
I'm rather confused about terminology.

I think a callback and a callable object are exactly the same thing and they're used like f in STL algorithms (or our own algorithm) when f is:
a regular function or
a pointer to function or
pointer to member function or
functor or
lambda expression or
std::function

Am I wrong?
Last edited on Aug 2, 2023 at 5:05pm
Aug 2, 2023 at 5:11pm
first, these are concepts, not precisely c++ specific syntax or tools. For that reason implementation details can vary, eg a functor could override [] instead of () if there were a reason (dealing with arrays/vectors perhaps) that made more sense to do so.

a callable object is what some call a functor .. its an object that acts like a function, really, and its class members generally track some sort of state (even as simple as total # of calls to it) that is important over time; a solid example is a random number generator object that overloads () to return the next value.

a callback is a placeholder in a generic function where the user provides part of the functionality. it can default to do nothing if not provided or be required; an example is standard sort where you have the option to provide a comparison function.

BECAUSE a functor looks like a function, you CAN have your callback function BE a functor. This sort of thing is why I had the preamble that its conceptual terminology more than c++ specific... these are things most OOP languages can do but the implementations vary and c++ being c++, it varies a fair bit within c++ as well.
Last edited on Aug 2, 2023 at 5:17pm
Aug 2, 2023 at 5:24pm
A callable is anything that has an operator(). It could be an object, a function, or a function pointer.
A callback is a general mechanism to modify the behavior of a function or to receive messages from a function that involves passing as a parameter to the function something that the function can call (back) to momentarily return control back to the caller.

A callback is always something you pass to a function. A callable could be used in ways other than as a parameter. For example, you could have a vector of functors that are supposed to be called in succession, or a function could return an std::function that the caller can call at its convenience:
1
2
3
4
5
6
7
8
9
10
11
12
13
class WeatherApi{
public:
    std::function<float()> get_temperature_interface();
};

//...

//get_temp is not a callback!
auto get_temp = api.get_temperature_interface();
while (true){
    std::cout << get_temp() << std::endl;
    sleep(1000);
}
Aug 2, 2023 at 7:06pm
A callable is anything that has an operator(). It could be an object, a function, or a function pointer.
Or a lambda expression

So a callback is actually the name of a callable when it appears for that purpose as an argument of another callable. Right?
Aug 2, 2023 at 7:36pm
Lambda expressions are not callable, they evaluate to lambda objects, which are themselves callable. Note that the type of the lambda object is unspecified.

So a callback is actually the name of a callable when it appears for that purpose as an argument of another callable. Right?
I avoided using the word "callable" in my definition of callback because "callable" is a C++ concept, but callbacks are used in basically every language. But if we're talking just about C++, the callback is the callable that is passed, not its name.
1
2
3
void foo(const std::function<void()> &cb);

foo([](){ std::cout << "hello"; });
The callback is [](){ std::cout << "hello"; }, not cb.
Last edited on Aug 2, 2023 at 7:37pm
Aug 2, 2023 at 7:57pm
Can we say a lambda object is a callable?

I said ... as an argument ..., i,e, when it's used as an argument in a call. So a callback is actually the name of a callable, or a lambda expression, when it appears for that purpose as an argument of another callable.
Still not right?
Aug 2, 2023 at 11:31pm
In my previous example, the callback is a lambda and thus has no name. There's a reference to it and its name is cb, but cb is not the callback, it's a reference to the callback, just like how here
1
2
void foo(int &x){
}
x is not the number, it's a reference to the number. Even if you're not passing a lambda, remember that when you pass by reference there may be more than one name that refers to the same object.
1
2
3
4
5
6
void foo(SomeFunctor &bar){
    bar();
}

auto snafu = std::make_unique<SomeFunctor>();
foo(*snafu);
What's the callback's name? Is it snafu or bar? The answer is neither. Objects don't have names. Locals, globals, and members have names. bar is a local parameter that points to a callback, and snafu is a local smart pointer that points to an object that's about to be used as a callback.
Aug 3, 2023 at 8:57am
OK, thank you very much.
Topic archived. No new replies allowed.