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/fu
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;
}
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 :)
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>... >
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.
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.
In C++20 this is possible using the following syntax:
auto lambda = []<typename T>(T t){
// do something
};