Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Lambdas and template parameter deduction

66 views
Skip to first unread message

Juha Nieminen

unread,
Sep 22, 2015, 9:57:02 AM9/22/15
to
Consider the following:

//--------------------------------------------------------------------
template<int Amount, typename Elem_t>
void foo(Elem_t(*func)(int)) {}

int bar(int i) { return i; }

int main()
{
foo<10>(bar); // Compiles

foo<10>([](int i)->int { return i; }); // Does not compile

foo<10, int>([](int i)->int { return i; }); // Compiles
}
//--------------------------------------------------------------------

(At least so with clang.)

With the regular old function, foo() can be called without having to
specify the second template parameter. However, with lambdas it has
to be specified. Why?

--- news://freenews.netfront.net/ - complaints: ne...@netfront.net ---

Öö Tiib

unread,
Sep 22, 2015, 10:45:50 AM9/22/15
to
On Tuesday, 22 September 2015 16:57:02 UTC+3, Juha Nieminen wrote:
> Consider the following:
>
> //--------------------------------------------------------------------
> template<int Amount, typename Elem_t>
> void foo(Elem_t(*func)(int)) {}
>
> int bar(int i) { return i; }
>
> int main()
> {
> foo<10>(bar); // Compiles
>
> foo<10>([](int i)->int { return i; }); // Does not compile
>
> foo<10, int>([](int i)->int { return i; }); // Compiles
> }
> //--------------------------------------------------------------------
>
> (At least so with clang.)
>
> With the regular old function, foo() can be called without having to
> specify the second template parameter. However, with lambdas it has
> to be specified. Why?

Seems that you hope template argument deduction to be too wise?
AFAIK implicit conversions are not considered during template
argument deduction. With explicit conversion it works:

foo<10>((int(*)(int))[](int i)->int { return i; });

Vir Campestris

unread,
Sep 22, 2015, 4:41:52 PM9/22/15
to
I'm puzzled too. He's explicitly stated that his lambda returns an int;
it looks to me as if the type of his lambda ought to be int(*)(int),
which ought to be enough for the deduction.

Andy

Chris Vine

unread,
Sep 22, 2015, 5:57:41 PM9/22/15
to
Its type is not int(*)(int). The type of a lambda expression is a
function object of unspecified type (namely it "is a unique, unnamed
non-union class type" which "has a public inline function call
operator"). (Quotes are from the C++ standard.)

Because in the case referred to in the original posting there is no
captured environment (the capture list is empty), the lambda expression
is implicitly convertible to a function pointer of type int(*)(int),
which is not the same thing at all.

Chris

nameku...@gmail.com

unread,
Oct 18, 2015, 1:39:33 AM10/18/15
to
LOL

all the convenience of manually-captured closures with the generalized benefits of templates with no type inference and schizophrenic type signatures...
0 new messages