Generic lambdas Vs标准模板函数(使用什么和何时)

Ram*_*Ram 5 c++ generics lambda c++11 c++14

通用Lambda是一种定义lambdas的方法,其内容如下:

auto identity = [](auto a){return a;}
Run Code Online (Sandbox Code Playgroud)

比较这个:

template <typename T>
T Identity(T t){return t;}
Run Code Online (Sandbox Code Playgroud)

或者

template <typename T> 
struct Identity { T operator()(T a) { return a; } };
Run Code Online (Sandbox Code Playgroud)

这是我的理解

  1. lambdas允许使用[&],[=]等进行上下文捕获,我不确定如何在通用lambda中使用/应用它.这是主要区别吗?

  2. 通用lambdas可以转换为函数指针,而模板特化可以转换为函数指针.

一个简单的现实世界示例将有助于了解使用什么和何时使用.

[附加]以下是通用的lambda提案:http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3559.pdf

Die*_*ühl 6

与lambdas非常相似,泛型lambda通过等效于隐式定义的函数对象来定义(其中非泛型lambdas具有额外的能力,使用空捕获它们可以转换为函数指针).泛型和非泛型lambda之间唯一真正的区别是泛型lambda有一个调用操作符,它是一个函数模板,而它是非泛型lambdas的非模板.

  1. 对于通用lambda,不存在转换为函数指针(参见5.1.2 [expr.prim.lambda]第6段).
  2. 由于泛型lambda仍然是带有调用操作符的对象,因此它们可以直接用作可以使用泛型函数对象的参数.对于函数模板来说情况并非如此:这些函数更像是一个重载集,您需要在将它们作为函数对象传递之前进行实例化.
  3. 虽然您无法获得指向函数模板的指针,但您可以获得指向函数模板特化的指针(正如@Columbo在注释中指出的那样,函数模板特化是一个函数).你不能从泛型lambda中获得指向函数的指针.
  4. 函数模板参与重载解析,而函数对象并不真正参与:当在名称查找期间找到对象时,即使可能存在具有相同名称且具有良好匹配的重载函数,也会选择此对象.这意味着,这两者并不等同:

    template <typename T>
    auto identity(T value) { return value; }
    auto identity = [](auto value) { return value; }
    
    Run Code Online (Sandbox Code Playgroud)

    第二个实现劫持名称,而前者用作重载决策的候选者.

除了从函数内创建的辅助对象之外,我将使用通用lambda来表示不是定制点的函数(例如,如果标准库算法是这样的对象,那将会很好).主要好处是可以容易地调整功能对象,例如,std::bind()对于功能模板不适用.