C++0x 的 lambda 表达式没有命名类型是不是很糟糕?
我最近在互联网上阅读了一些有关 lambda 表达式的内容,在我看来,C++0x 的 lambda 表达式不会有一个(或多个)类型专门绑定到 lambda 表达式 - 换句话说,lambda表达式仅匹配模板参数或自动参数/变量。会发生什么,如所述这里,就是
支持 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
)真的有意义吗?
I've been reading a bit about lambda expressions on the internet recently and it seems to me that C++0x's lambda expressions will not have a single type (or types) that will bind exclusively to lambda expressions -- in other words, lambda expressions will only match template arguments or auto
arguments/variables. What happens, as described here, is that
Compilers that support lambdas will
create a unique anonymous functor type
for each lambda expression
My question is, is that a bad thing? Wouldn't it make sense to have some keyword that matches only to lambda expressions, e.g. lambda
, which would work as follows
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;
}
To be honest, I actually can't see the usefulness of this (especially given that auto
accepts lambda expressions, so one could then assign a lambda to a variable), but it still doesn't sit right with me that lambda expressions are anonymous types and cannot be bound specifically to just one particular type (to the exclusion of all others).
In essence, my question is, is it fine that lambda expressions are anonymous (both in terms of utility -- does the lack of a lambda
type devoid us of some functionality -- and philosophically -- does it really make sense that lambda expressions always have the 'type' auto
)?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
Lambda 是独立类型。该代码
没有任何意义,因为 lambda 不具有运行时多态性。回想一下,lambda 相当于
它本身就是一个唯一的类型。上面的代码与“Which”相同,
即使我们确保 C 有
operator()
也是没有意义的。您需要一个模板:Lambdas are independent types. The code
doesn't make any sense because lambdas don't have runtime polymorphism. Recall that a lambda is the equivalent of
Which is itself a unique type. The code above would be the same as saying
Which also makes no sense even if we assure that C has
operator()
. You need a template:我认为没有理由根据函数是否有名称来区分函数类型。 Lambda 函数只是一种简写,允许您轻松定义便利函数。无论有名称还是没有名称,调用函数时的行为都是相同的。
这样想吧。软件的早期版本有一个定义为匿名函数的谓词。随着时间的推移,需求变得更加复杂,你的谓词也变得更加复杂——也许你需要从多个地方调用它。明智的做法是重构,以便拥有一个命名函数。
被调用的函数(调用谓词的函数)没有理由关心这一点。简单或复杂,命名或匿名 - 它仍然只是一个谓词函数。
一个小问题是闭包 - 我还没有检查过,但运气好的话,C++ 将获得带有闭包和 lambda 的嵌套命名函数。
I see no reason to differentiate function types based on whether the function has a name or not. Lambda functions are just a shorthand, allowing you to define a convenience function easily. Name or no name, the behaviour of the function when called is the same.
Think of it this way. An early version of your software has a predicate defined as an anonymous function. Over time, requirements get more complex, and your predicate gets more complex too - and maybe you need to call it from more than one place. The sensible thing to do is to refactor so that you have a named function.
There's no reason why the called function (the one that calls the predicate) should care about that. Simple or complex, named or anonymous - it's still just a predicate function.
One minor issue is that of closures - I haven't checked, but with a bit of luck, C++ will get nested named functions with closures as well as lambdas.