C ++ 0x的lambda表达式没有命名类型是不是很糟糕?

时间:2009-09-29 18:13:21

标签: c++ lambda c++11

我最近在互联网上阅读了一些关于lambda表达式的内容,在我看来,C ++ 0x的lambda表达式不会只有一种类型(或类型)只能绑定到lambda表达式 - 在其他单词,lambda表达式只匹配模板参数或auto参数/变量。如here所述,会发生什么

  

支持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表达式总是有'type'auto)?

2 个答案:

答案 0 :(得分:11)

Lambdas是独立的类型。代码

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

答案 1 :(得分:3)

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

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

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

一个小问题是闭包问题 - 我没有检查过,但运气好的话,C ++将获得带闭包和lambdas的嵌套命名函数。