lambda函数可以模板化吗?

在C ++ 11中,有没有办法模拟一个lambda函数? 或者它本身是太具体的模板?

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

2014年更新:C ++ 14今年已经发布,现在提供了与本例中相同语法的多形态lambda。 一些主要的编译器已经实现了它。


在它站立(在C + + 11),可悲的没有。 在灵活性和力量方面,多形性lambda将是优秀的。

他们最终成为单形的原因是因为概念。 概念使这个代码情况困难:

template <Constraint T> void foo(T x) { auto bar = [](auto x){}; // imaginary syntax } 

在受限制的模板中,您只能调用其他受约束的模板。 (否则,约束无法检查。)可以foo调用bar(x) ? lambda有什么限制(毕竟它的参数只是一个模板)?

概念还没有准备好处理这种事情; 它会需要更多的东西像late_check (其中的概念没有被检查,直到被调用)和东西。 更简单的是放弃所有,坚持单形lambda。

然而,随着从C ++ 0x中移除概念,多态lambdaexpression式再次成为一个简单的命题。 不过,我找不到任何build议。 🙁

C ++ 11 lambda不能像其他答案中所述的模板化,但decltype()似乎有助于在模板化类或函数中使用lambda。

 #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 

我发现这个技术在使用模板代码的时候是有帮助的,但是意识到它仍然意味着lambda本身不能被模板化。

在C ++ 11中,lambda函数不能被模板化,但在ISO C ++标准的下一个版本(通常称为C ++ 14)中,将引入这个特性。 [资源]

用法示例:

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

请注意,虽然语法使用关键字auto ,但types推导不会使用autotypes推导的规则,而是使用模板参数推导的规则。 另请参阅通用lambdaexpression式的提议 (以及对此的更新 )。

我知道这个问题是关于C ++ 11的。 然而,对于那些在这个页面上search和登陆的人来说,现在在C ++ 14中支持模板化的lambda,并且名为Generic Lambdas。

大多数stream行的编译器现在都支持这个function。 Microsoft Visual Studio 2015支持。 铿锵支持。 GCC支持。

我想知道这是什么:

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

我用类似的代码来生成一个模板,并想知道编译器是否会优化“包装”function。

看看Boost.Phoenix的多态lambdaexpression式: http : //www.boost.org/doc/libs/1_44_0/libs/spirit/phoenix/doc/html/index.html不需要C ++ 0x,由办法 :)

我不知道为什么没有人提出这个build议,但你可以写一个模板函数返回lambda函数。 以下解决了我的问题,我来到这个页面的原因:

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

现在,无论何时我需要一个接受给定types参数的函数(例如std::string ),我只是说

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

现在f("any string")返回1.0

这就是我所说的“模板化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); } ); 

_widgets是一个std::tuple< fusion::pair<Key_T, Widget_T>... >

这是一个解决scheme,涉及将lamba包装在一个结构中:

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

使用做:

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

这个主要问题(除了额外的input)你不能在另一个方法中embedded这个结构定义,或者你得到(gcc 4.9)

 error: a template declaration cannot appear at block scope 

我也试过这样做:

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

希望我能像这样使用它:

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

但是我得到的编译器错误:

 error: lambda-expression in unevaluated context 

所以这是行不通的,但即使编译也是有限的,因为我们仍然要把“使用LamdaT”放在文件范围(因为它是一个模板) lambdaexpression式。