[c++] Can lambda functions be templated?

In C++11, is there a way to template a lambda function? Or is it inherently too specific to be templated?

I understand that I can define a classic templated class/functor instead, but the question is more like: does the language allow templating lambda functions?

This question is related to c++ templates lambda c++11

The answer is


Here is one solution that involves wrapping the lamba in a structure:

template <typename T>                                                   
struct LamT                                                             
{                                                                       
   static void Go()                                                     
   {                                                                    
      auto lam = []()                                                   
      {                                                                 
         T var;                                                         
         std::cout << "lam, type = " << typeid(var).name() << std::endl;
      };                                                                

      lam();                                                            
   }                                                                    
};   

To use do:

LamT<int>::Go();  
LamT<char>::Go(); 
#This prints 
lam, type = i
lam, type = c

The main issue with this (besides the extra typing) you cannot embed this structure definition inside another method or you get (gcc 4.9)

error: a template declaration cannot appear at block scope

I also tried doing this:

template <typename T> using LamdaT = decltype(                          
   [](void)                                                          
   {                                                                 
       std::cout << "LambT type = " << typeid(T).name() << std::endl;  
   });

With the hope that I could use it like this:

LamdaT<int>();      
LamdaT<char>();

But I get the compiler error:

error: lambda-expression in unevaluated context

So this doesn't work ... but even if it did compile it would be of limited use because we would still have to put the "using LamdaT" at file scope (because it is a template) which sort of defeats the purpose of lambdas.


C++11 lambdas can't be templated as stated in other answers but decltype() seems to help when using a lambda within a templated class or function.

#include <iostream>
#include <string>

using namespace std;

template<typename T>
void boring_template_fn(T t){
    auto identity = [](decltype(t) t){ return t;};
    std::cout << identity(t) << std::endl;
}

int main(int argc, char *argv[]) {
    std::string s("My string");
    boring_template_fn(s);
    boring_template_fn(1024);
    boring_template_fn(true);
}

Prints:

My string
1024
1

I've found this technique is helps when working with templated code but realize it still means lambdas themselves can't be templated.


I wonder what about this:

template <class something>
inline std::function<void()> templateLamda() {
  return [](){ std::cout << something.memberfunc() };
}

I used similar code like this, to generate a template and wonder if the compiler will optimize the "wrapping" function out.


There is a gcc extension which allows lambda templates:

// create the widgets and set the label
base::for_each(_widgets, [] <typename Key_T, typename Widget_T>
                         (boost::fusion::pair<Key_T, Widget_T*>& pair) -> void {
                             pair.second = new Widget_T();
                             pair.second->set_label_str(Key_T::label);
                          }
              );

where _widgets is a std::tuple< fusion::pair<Key_T, Widget_T>... >


In C++11, lambda functions can not be templated, but in the next version of the ISO C++ Standard (often called C++14), this feature will be introduced. [Source]

Usage example:

auto get_container_size = [] (auto container) { return container.size(); };

Note that though the syntax uses the keyword auto, the type deduction will not use the rules of auto type deduction, but instead use the rules of template argument deduction. Also see the proposal for generic lambda expressions(and the update to this).


I am aware that this question is about C++11. However, for those who googled and landed on this page, templated lambdas are now supported in C++14 and go by the name Generic Lambdas.

[info] Most of the popular compilers support this feature now. Microsoft Visual Studio 2015 supports. Clang supports. GCC supports.


Have a look at Boost.Phoenix for polymorphic lambdas: http://www.boost.org/doc/libs/1_44_0/libs/spirit/phoenix/doc/html/index.html Does not require C++0x, by the way :)


In C++20 this is possible using the following syntax:

auto lambda = []<typename T>(T t){
    // do something
};

I've been playing with the latest clang version 5.0.1 compiling with the -std=c++17 flag and there is now some nice support for auto type parameters for lambdas:

#include <iostream>
#include <vector>
#include <stdexcept>

int main() {
    auto slice = [](auto input, int beg, int end) {
        using T = decltype(input);
        const auto size = input.size();
        if (beg > size || end > size || beg < 0 || end < 0) {
            throw std::out_of_range("beg/end must be between [0, input.size())");
        }
        if (beg > end) {
            throw std::invalid_argument("beg must be less than end");
        }
        return T(input.begin() + beg, input.begin() + end);
    };
    auto v = std::vector<int> { 1,2,3,4,5 };
    for (auto e : slice(v, 1, 4)) {
        std::cout << e << " ";
    }
    std::cout << std::endl;
}

I'm not sure why nobody else has suggested this, but you can write a templated function that returns lambda functions. The following solved my problem, the reason I came to this page:

template <typename DATUM>
std::function<double(DATUM)> makeUnweighted() {
  return [](DATUM datum){return 1.0;};
}

Now whenever I want a function that takes a given type of argument (e.g. std::string), I just say

auto f = makeUnweighted<std::string>()

and now f("any string") returns 1.0.

That's an example of what I mean by "templated lambda function." (This particular case is used to automatically provide an inert weighting function when somebody doesn't want to weight their data, whatever their data might be.)


Examples related to c++

Method Call Chaining; returning a pointer vs a reference? How can I tell if an algorithm is efficient? Difference between opening a file in binary vs text How can compare-and-swap be used for a wait-free mutual exclusion for any shared data structure? Install Qt on Ubuntu #include errors detected in vscode Cannot open include file: 'stdio.h' - Visual Studio Community 2017 - C++ Error How to fix the error "Windows SDK version 8.1" was not found? Visual Studio 2017 errors on standard headers How do I check if a Key is pressed on C++

Examples related to templates

*ngIf else if in template 'if' statement in jinja2 template How to create a link to another PHP page Flask raises TemplateNotFound error even though template file exists Application not picking up .css file (flask/python) Django: How can I call a view function from template? Angularjs Template Default Value if Binding Null / Undefined (With Filter) HTML email in outlook table width issue - content is wider than the specified table width How to redirect on another page and pass parameter in url from table? How to check for the type of a template parameter?

Examples related to lambda

Java 8 optional: ifPresent return object orElseThrow exception How to properly apply a lambda function into a pandas data frame column What are functional interfaces used for in Java 8? Java 8 lambda get and remove element from list Variable used in lambda expression should be final or effectively final Filter values only if not null using lambda in Java8 forEach loop Java 8 for Map entry set Java 8 Lambda Stream forEach with multiple statements Java 8 stream map to list of keys sorted by values Task.Run with Parameter(s)?

Examples related to c++11

Remove from the beginning of std::vector Converting std::__cxx11::string to std::string What exactly is std::atomic? C++ How do I convert a std::chrono::time_point to long and back Passing capturing lambda as function pointer undefined reference to 'std::cout' Is it possible to use std::string in a constexpr? How does #include <bits/stdc++.h> work in C++? error::make_unique is not a member of ‘std’ no match for ‘operator<<’ in ‘std::operator