6

我最近在互联网上阅读了一些关于 lambda 表达式的内容,在我看来,C++0x 的 lambda 表达式不会有一个(或多个类型)专门绑定到 lambda 表达式——换句话说,lambda表达式只会匹配模板参数或auto参数/变量。如此处所述会发生什么

支持 lambda 的编译器将为每个 lambda 表达式创建一个唯一的匿名函子类型

我的问题是,这是一件坏事吗?有一些只匹配 lambda 表达式的关键字是否有意义,例如lambda,它的工作方式如下

void f(std::function<int(int)> func)
{
     func(2);
}

template<typename T>
void g(T func)
{
     func(2);
}

void h(lambda func)
{
     func(2);
}

int main()
{
    int fpointer(int);
    struct { int operator()(int var) { return var; } } functor;

    f(fpointer); //ok (actually a linker error, but for the sake of example)
    f(functor); //ok
    f([](int var) { return var; }); //ok

    g(fpointer); //ok
    g(functor); //ok
    g([](int var) { return var; }); //ok

    h(fpointer); //error -- function pointer isn't a lambda expr
    h(functor); //error -- functor isn't a lambda expr
    h([](int var) { return var; }); //ok

    return 0;
}

老实说,我实际上看不到它的用处(特别是考虑到auto接受 lambda 表达式,因此可以将 lambda 分配给一个变量),但我仍然认为 lambda 表达式是匿名类型并且不能专门绑定到一种特定类型(排除所有其他类型)。

从本质上讲,我的问题是,lambda 表达式是匿名的是否可以(无论是在实用性方面 - 缺乏lambda类型是否使我们失去了某些功能 - 并且在哲学上 - lambda 表达式总是有意义吗? '类型' auto)?

4

2 回答 2

11

Lambda 是独立的类型。编码

void h(lambda func)
{
     func(2);
}

没有任何意义,因为 lambdas 没有运行时多态性。回想一下,lambda 相当于

struct unique_name
{
    return_type operator()(Arg1 a1, Arg2 a2, ... , Argn an)
    {
        code_inside_lambda;
    }
}

这本身就是一种独特的类型。上面的代码和说的一样

void h(class C)
{
     C(2);
}

即使我们保证 C 有,这也是没有意义的operator()。你需要一个模板:

template<typename T>
void g(T func)
{
     func(2);
}

int main()
{
    g([](int x){return x + 2;});
}
于 2009-09-29T18:24:58.870 回答
3

我认为没有理由根据函数是否有名称来区分函数类型。Lambda 函数只是一种简写形式,让您可以轻松定义便利函数。有名或无名,调用时函数的行为是相同的。

这样想吧。您的软件的早期版本具有定义为匿名函数的谓词。随着时间的推移,需求变得更加复杂,您的谓词也变得更加复杂——也许您需要从多个地方调用它。明智的做法是重构,以便您拥有一个命名函数。

被调用函数(调用谓词的函数)没有理由关心这一点。简单或复杂,命名或匿名 - 它仍然只是一个谓词函数。

一个小问题是闭包——我还没有检查过,但幸运的是,C++ 将获得带有闭包和 lambda 的嵌套命名函数。

于 2009-09-29T18:25:20.587 回答