Reputation: 24750
I've used auto
to store a lambda that is constructed right in the auto assignment, but today I was looking at this interesting paper on functional programming using c++ templates and came across this code:
template < typename T , typename Ops >
T fold ( Linked <T > * p )
{
T acc = Ops :: initial () ;
while ( p ) {
acc = Ops :: bin ( acc , p - > head ) ;
p = p - > tail ;
}
return acc ;
}
// later, in main():
auto sumup = fold <int , IntOps >;
I am trying to understand what the type of sumup
would be, since it is assigned not to the output of fold
but rather to the actual function fold
itself! I decided to take a look at the various ways auto
is shown to be used here. I am assuming that this use of auto
falls under (1)
on that page, a general variable initializer. What is not clear is what is the type of sumup
?
And, would auto
potentially be the same here as doing this:
using functionType = int (Linked<int>*);
functionType sumup = fold <int , IntOps >;
This is probably not correct, but I'd be curious if my thinking is in the right direction. When instantiated, fold <int , IntOps >
will be a function that returns an int
and taking a single argument of Linked<int>*
, so my using
declaration is saying the same thing? Is this using
declaration a bonafide "type" and is the auto
arriving at the same deduction as this using
?
Upvotes: 1
Views: 179
Reputation: 179779
While every function has a type, you cannot have expressions of that type, nor variables. So int foo(float)
has type int(float)
, for instance, but you cannot have a variable of that type.
You can have expressions and variables of type pointer to function, so int(*)(float)
. For instance, &foo
is such a pointer to function.
The two types are quite closely related, obviously. In fact, the conversion is implicit: int (*pFoo)(float) = foo;
does the conversion automatically.
What you do here is pretty much the same: int (*sumup)(Linked<int>*) = fold <int , IntOps >;
. You see that auto
makes the definition much more readable.
Upvotes: 1
Reputation: 8141
auto
works by the same rules as template argument deduction. That is, when unqualified, it will take things by value. Since here you're returning a function reference, it will have to decay down to a pointer, because there's no "value type" for a function, with a specific size and whatnot.
You could also capture with auto&&
which would make the type of sumup
be int (&)(Linked<int>*)
, i.e. a reference to the function.
Upvotes: 1