sap
sap

Reputation: 1228

pass function by value (?) instead of function pointer?

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

Answers (4)

PeterSom
PeterSom

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

deft_code
deft_code

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

hamstergene
hamstergene

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

James McNellis
James McNellis

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

Related Questions