Reputation: 1228
Sorry if this has been asked before, but I was unable to find it.
So im trying to educate myself about templates and the new C++11 features (mainly lambdas, something I always liked in other languages).
But in my tests I came to something I had no idea it worked, and I'm trying to understand how it works but cant figure it out..
The following code:
template <class Func>
void Test( Func callback ) {
callback( 3 );
}
void Callback( int i ) {
std::cout << i << std::endl;
}
int main( int argc, char** argv ) {
Test( &Callback ); // this I was expecting to work, compiler will see its a pointer to a function
Test( Callback ); // this also works, but how?!
return 0;
}
If I understand how templates work, basically they're a scheme for the compiler to know what to build, so the first call Test( &Callback );
I was expecting to work because the compiler will see the template receives a function address and will assume the arguments should be a pointer.
But what is the second call? What is the template assuming it is? A copy of a functio (if that even makes any sense)?
Upvotes: 15
Views: 3522
Reputation: 2187
In C++ 11 (and boost and tr1) we have std::function as a template type for storing functors, lambdas and functions. So you can definitely have the concept of keeping a function value in a variable of type std::function. that variable can also be "empty" meaning that no function (reference) is stored in it. Then it cannot be called.
The original question relates to that in contrast to C, C++ allows function references. Plus, for compatibility reasons with C a function name can degenerate to a function pointer. But because of overloading things are more "interesting" in C++ than in C.
Upvotes: 0
Reputation: 59269
Functions are implicitly convertible to function pointers. If fact there is no way to get a function value or reference. Though oddly you can create a function value type, you just can't assign anything to it.
Here is code snippit that demonstrates how lambdas and various callbacks react with templates.
Upvotes: 3
Reputation: 24439
In C++, functions are not first-class objects, which means “function as value” makes no sense in it. That's why function name has always been implicitly convertible to pointer to it.
Upvotes: 2
Reputation: 355069
A function is implicitly convertible to a pointer to itself; this conversion happens pretty much everywhere. Test(Callback)
is exactly the same as Test(&Callback)
. There is no difference. In both cases, Func
is deduced to be void(*)(int)
.
Function pointers are weird. You can find out more about them in "Why do all these crazy function pointer definitions all work?"
Upvotes: 19