Search code examples
c++templateslambdac++20

What is the type of a templated lambda?


The following code tries to create a templated lambda and pass it to a function that calls it. However compilation fails because the type of lambda argument is wrong.

#include <functional>

void foo(std::function<void(void)>&lambda) {
  lambda.template operator()<int>();
}

int main() {
  auto f = []<class T>() {};
  foo(f);
}

How should I define the type of an argument that receives a templated lambda?

Using auto works but I need the explicit type (so I can modify foo to return whatever the lambda returns).

void foo(auto &lambda) { // Works but not what I want

I tried this but doesn't compile:

template<class T>
void foo(std::function<void<T>(void)>&lambda) {

Solution

  • The difference between what you call a templated lambda and an ordinary lambda is that the operator() is a template. Otherwise there is no much difference between the type of the lambda itself. Its a unique unnamed type.

    How should I define the type of an argument that receives a templated lambda?

    The same as of a non-templated lambda.

    ... but I need the explicit type (so I can modify foo to return whatever the lambda returns).

    You do not need to know the type of the lambda for that because you can use auto return type:

     auto foo(auto &lambda) {
            auto ret = lambda.template operator()<int>();
            return ret;
     }
    

    The type of the lambda is decltype(lambda) and the return type of its operator() when instantiated with int is decltype(lambda.operator()<int>()) (add std::decay_t if needed).


    PS: std::function is generally not the type you should use always when passing a callable to a function. std::function is primarily for type erasure which you do not need here. If you use it merely for convenience then one day you will feel betrayed for the price you pay for something you do not use.