std::function
itself offers a great utility- it provides type erasure in order to generically store / provide access to callables. Its flexibility is great:
#include <functional>
#include <iostream>
void printer() {
std::cout << "I print!";
}
int adder(int a, int b) {
return a + b;
}
int main() {
std::function<void()> fun1 = printer; // fun1() calls printer()
std::function<int(int, int)> fun2 = adder; // fun2(1, 2) calls adder(1, 2)
std::function<void()> fun3 = [](){}; // fun3() will do nothing - same for the lambda
std::function<int(int, int)> fun4 =
[](int a, int b) { return a + b; }; // fun4(1, 2) will yield the sum
}
And, to be honest, everything makes sense. std::function<void()>
says that it's a function
, which, when called, returns void
and takes no (()
) arguments. Ditto for std::function<int(int, int)>
- when called, it returns an int
and requires two int
s as its arguments.
While intuitive, I believe I lack fundamental understanding of that exactly is the explicit template parameter. What exactly is void()
or int(int, int)
? They cannot be function pointers, becasue when I do:
int main() {
using type = void();
type x = printer;
}
I get the following warning and an error:
main.cpp:15:10: warning: declaration of 'void x()' has 'extern' and is initialized type x = printer; ^ main.cpp:15:14: error: function 'void x()' is initialized like a variable type x = printer; ^~~~~~~
Well, obviously it looks like a variable - I wanted it to be a variable. However, if I wanted a function pointer, I would've had to do:
using type = void(*)();
instead of:
using type = void();
What exactly is the type with omitted *
? What exactly is represented by the intuitive explicit template parameters when used with, for example, the std::function
?
What exactly is the type with omitted *?
Think about it. A type "followed by" a *
means "pointer to that type". If you don't "follow" a type with a *
, then the type means just that type. So if you have a function pointer, then it is a pointer to... a function type.
Therefore, types like void()
are function types.
Function types are distinct from object types, but they are still types. So you can play most of the type-based games with them that C++ allows. But since they're not object types, you cannot create objects of function type.