I am trying to understand the difference between function types <void()> and function pointer types <void (*)()>
stl::function can point to functions through <void()>, but I seem to need to use <void (*)()> in my own template classes:
void f1() {
std::cout << "hi!\n";
}
template<class T> struct X
{
T t;
};
int main()
{
std::function<void()> f = f1; // stl handles this, and f is callable
f(); // OK
// X<void()> x; // compilation error - a member of a class template cannot aquire a function type
X<void (*)()> x2; // OK
x2.t = f1; // OK
x2.t(); // OK
return 0;
}
Are function types such as <void()> new to C++ 11, and introduced along with std::function?
I have seen some other questions regarding this, but have not found an explanation which is clear to me, and searching the web for C++ function type does not yield satisfactory results.
I would greatly appreciate any clear explanation or references to one.
Function types aren’t new to C++11 at all: the existed even in C. However, you cannot have objects of function types, i.e.,
template <typename T>
struct X {
T t;
};
X<void()> does_not_work;
X<void(*)()> works;
However, you can turn a function type into a pointer type:
template <typename T>
struct X {
T* t;
};
Upon using a function differently than calling it the function decays into a function pointer. Decaying a function into a pointer is equivalent to taking the function’s address.
Of course, what std::function<...> does is quite different anyway: it actually defines a function call operator. To do so it deckares a general template and specializes it for function types:
template <typename> class function;
template <typename R, typename... A>
class function<R(A...)> {
public:
R operator()(A...);
// ...
};
You can't store a function in a variable, you can only store a function pointer. What is slightly confusing is that the language automatically converts a function into a function pointer when you try to assign the function name to a variable.
Your class would have to be:
template<class T> struct X
{
T* t;
};
To make X<void()> x work. This would of course stop X<void (*)()> x2 from working, you'd have to specialise the template for different types.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With