Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

compile-time conversion of lambda functors into function pointers

Tags:

c++

c++11

As we know, non-capturing lambda functors can be converted to function pointers at runtime, but how about compile time? That is, is something similar to the code below possible? Please don't suggest a workaround, like passing the lambda functor as a function parameter, I'd like to know more where/how the C++11 standard forbids this.

template <void(*fptr)()>
void f()
{
  // do something
}

int main()
{
  auto l([]{});

  f<(void(*)())(decltype(l))>();

  return 0;
}

The obligatory error with gcc-4.8:

c.cpp: In function 'int main()':
c.cpp:11:7: error: parse error in template argument list
       f<(void(*)())(decltype(l))>();
       ^
c.cpp:11:36: error: statement cannot resolve address of overloaded function
       f<(void(*)())(decltype(l))>();
                                    ^
like image 516
user1095108 Avatar asked Nov 02 '22 15:11

user1095108


1 Answers

Lambda expressions, even with an empty closure, can not be used as a pointer to function template argument because they are temporaries which just happen to convert to some pointer to function. The lambda expression is a temporary according to 5.1.2 [expr.prim.lambda] paragraph 2:

The evaluation of a lambda-expression results in a prvalue temporary. [...]

The conversion to a pointer to function is desribed in paragraph 6:

The closure type for a lambda-expression with no lambda-capture has a public non-virtual non-explicit const conversion function to pointer to function having the same parameter and return types as the closure type’s function call operator. The value returned by this conversion function shall be the address of a function that, when invoked, has the same effect as invoking the closure type’s function call operator.

That is, the conversion doesn't yield a constexpr and, thus, there is no hope to use the resulting pointer to function as a template argument.

As for the reasons the best I could find for now is a statement in N3597 which points towards N2895 which seem to talk about the actual problem but I couldn't locate a detailed discussion. It seems that name-mangling for the functions created by lambda expressions is one of the problems which prohibits using them in certain contexts.

like image 189
Dietmar Kühl Avatar answered Nov 13 '22 08:11

Dietmar Kühl