在c++ 11中,是否有一种方法来模板lambda函数?还是它本身就太具体了,无法被模板化?

我知道我可以定义一个经典的模板化类/函子,但问题更像是:语言是否允许模板化lambda函数?


当前回答

在c++ 20中,可以使用以下语法:

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

其他回答

c++ 11 lambda不能像其他答案中所述的那样被模板化,但当在模板化的类或函数中使用lambda时,decltype()似乎有所帮助。

#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);
}

打印:

My string
1024
1

我发现这种技术在处理模板化代码时很有帮助,但意识到它仍然意味着lambdas本身不能被模板化。

看看Boost。用于多态lambdas的Phoenix: http://www.boost.org/doc/libs/1_44_0/libs/spirit/phoenix/doc/html/index.html 顺便说一下,不需要c++ 0x:)

c++ 11的另一个解决方法是定义一个模板函数并将其包装在lambda表达式中。然而;这需要为不同的模板化lambdas定义一个新函数:

struct ST{ int x; };

template<class T>
T templateFunc(T variable)
{
    return variable;
}

void func()
{
    ST st{10};
    auto lambda = [&](){return templateFunc<ST>(st);};
    auto res = lambda();
}

有一个允许lambda模板的gcc扩展:

// 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是一个std::tuple< fusion::pair<Key_T, Widget_T>…>

我知道这个问题是关于c++ 11的。然而,对于那些在谷歌上搜索并登陆这个页面的人来说,c++ 14现在支持模板化lambdas,并被称为泛型lambdas。

现在大多数流行的编译器都支持这个特性。微软Visual Studio 2015支持。叮当声的支持。GCC支持。