lambda函数可以模板化吗?

Kla*_*aim 210 c++ lambda templates c++11

在C++ 11中,有没有办法模板化lambda函数?或者它本身太具体而无法模板化?

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

GMa*_*ckG 166

更新2018年:C++ 20将带有模板化和概念化的lambda.该功能已经集成到标准草案中.


更新2014:C++ 14已于今年发布,现在提供的Polymorphic lambdas语法与此示例相同.一些主要的编译器已经实现了它.


在它的立场(在C++ 11中),遗憾的是没有.多态lambda在灵活性和功率方面都很出色.

他们最终变成单态的原因是因为概念.概念使这种代码情况变得困难:

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

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

概念还没有准备好解决这类问题; 它需要更多的东西late_check(如果概念在被调用之前没有被检查过)和东西.更简单的只是放弃所有并坚持单形lambda.

但是,随着从C++ 0x中删除概念,多态lambda再次成为一个简单的命题.但是,我找不到任何建议.:(

  • Polymorphic Lambdas将使用C++ 14,至少他们现在在社区草案中:) (17认同)
  • 您不必在概念和多态lambda之间做出选择:http://cpp-next.com/archive/2011/12/a-breakthrough-for-concepts/ (13认同)
  • 我想我宁愿拥有多态lambda而不是概念.我不明白这个例子是如何激励任何东西的; 你可以简单地禁止它作为一个错误,并要求lambda是单态[](T x){}或受约束的模板[]模板<Constraint T>(T x){},可以静态验证匹配.有什么理由说这是不可能的吗? (6认同)
  • 简单......除了希望重新引入概念并避免使其变得复杂的特征之外. (5认同)
  • 以下是多态lambda的建议:http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3418.pdf和clang中的玩具实现:http://faisalv.github. COM /铛,glambda / (3认同)

Joe*_*oel 36

C++ 11 lambdas不能像其他答案中所述那样进行模板化,但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);
}
Run Code Online (Sandbox Code Playgroud)

打印:

My string
1024
1
Run Code Online (Sandbox Code Playgroud)

我发现这种技术在使用模板化代码时很有帮助,但实现它仍然意味着lambdas本身不能被模板化.

  • 在这个例子中,`T`可以正常代替`decltype(t)`. (25认同)

Tim*_*ann 24

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

用法示例:

auto get_container_size = [] (auto container) { return container.size(); };
Run Code Online (Sandbox Code Playgroud)

请注意,尽管语法使用关键字auto,但类型推导不会使用auto类型推导的规则,而是使用模板参数推导的规则.另请参阅有关通用lambda表达式提议(以及对此的更新).

  • "auto"类型推导的规则被明确定义为与`template`函数参数推导的规则相同. (5认同)

shi*_*lch 15

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

auto lambda = []<typename T>(T t){
    // do something
};
Run Code Online (Sandbox Code Playgroud)

  • 这是否意味着我们现在可以编写像这样的 lambda `[]&lt;&gt;(){}`? (12认同)
  • 如果您需要在调用 lambda 时显式指定模板参数,我发现这是我的用例中的常见需求(例如,如果上面的示例中不存在“T t”参数),那么您可以使用这个语法:`lambda.template operator()&lt;int&gt;()`。有关更多信息,请参阅 /sf/ask/3457491691/。 (5认同)
  • @Arda为什么我们不能有一些“lambda&lt;int&gt;()”。这有技术限制吗? (5认同)
  • @tartaruga_casco_mole `lambda` 是一个函数对象。要使用模板尖括号,您需要一个类型(或 constexpr 模板)。我假设根据规范,编译器必须将示例中的“&lt;”视为“lambda”对象上的小于运算符,这显然会失败。未来的 C++ 版本可能允许以这种方式调用模板化的“operator()”。 (5认同)
  • @tartaruga_casco_mole 有趣的是,如果确实有效,则可能会产生不明确的语法:“lambda&lt;a&gt;(b)”可以是“lambda.operator()&lt;a&gt;(b)”或“lambda.operator&lt;(a)” .运算符&gt;(b)` (2认同)

Ram*_*Ram 9

我知道这个问题是关于C++ 11的.但是,对于那些使用Google搜索并登陆此页面的人,现在在C++ 14中支持模板化lambda,并使用名称Generic Lambdas.

[info]大多数流行的编译器现在都支持这个功能.Microsoft Visual Studio 2015支持.Clang支持.GCC支持.


ted*_*ted 6

我想知道这是怎么回事:

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

我使用类似这样的代码来生成模板,并想知道编译器是否会优化"包装"功能.

  • 什么编译器?做到了? (2认同)

小智 5

有一个gcc 扩展允许lambda 模板

// 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);
                          }
              );
Run Code Online (Sandbox Code Playgroud)

哪里_widgetsstd::tuple< fusion::pair<Key_T, Widget_T>... >