可以“类型”吗? lambda 表达式的表达方式?
将 lambda 表达式视为可调用对象的“语法糖”,是否可以表达未命名的基础类型?
一个例子:
struct gt {
bool operator() (int l, int r) {
return l > r;
}
} ;
现在,[](int l, int r) { return l >; r; }
是上述代码的优雅替代(加上必要的 gt 可调用对象的创建),但是有没有办法表达 gt (类型)本身?
一个简单的用法:
std::set<int, gt> s1; // A reversed-order std::set
// Is there a way to do the same using a lambda?
std::set<int, some-magic-here-maybe([](int l, int r) { return l > r; }) > s2;
Thinking of lambda expressions as 'syntactic sugar' for callable objects, can the unnamed underlying type be expressed?
An example:
struct gt {
bool operator() (int l, int r) {
return l > r;
}
} ;
Now, [](int l, int r) { return l > r; }
is an elegant replacement for the above code (plus the necessary creation of callable objects of gt), but is there a way to express gt (the type) itself?
A simple usage:
std::set<int, gt> s1; // A reversed-order std::set
// Is there a way to do the same using a lambda?
std::set<int, some-magic-here-maybe([](int l, int r) { return l > r; }) > s2;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
不,你不能将它放入
decltype
因为尽管您可以执行以下操作
,但这确实很难看。请注意,每个 lambda 表达式都会创建一个新的唯一类型。如果之后您在其他地方执行以下操作,
t
的类型与s
不同,您可以在此处使用
std::function
,但请注意,这会产生一点点运行时成本,因为它需要间接调用 lambda 函数对象调用运算符。它在这里可能可以忽略不计,但如果您想以这种方式将函数对象传递给std::sort
例如,它可能很重要。一如既往,先编码,然后分析:)
No, you cannot put it into
decltype
becauseYou can do the following though
But that is really ugly. Note that each lambda expression creates a new unique type. If afterwards you do the following somewhere else,
t
has a different type thans
You can use
std::function
here, but note that this will incur a tiny bit of runtime cost because it needs an indirect call to the lambda function object call operator. It's probably negligible here, but may be significant if you want to pass function objects this way tostd::sort
for example.As always, first code then profile :)
直接回答你的问题:不。
你需要使用可以从任何类型(类似于具有明确定义类型的函子)分配的东西。一个例子是 std::function,如 sbi 的答案所示。然而,这不是 lambda 表达式的类型。
Direct answer to your question: No.
You'll need to use something that is assignable from any type resembling a functor that has a well defined type. One example is std::function as shown in sbi's answer. That isn't, however, the type of the lambda expression.
从 C++ 20 开始,不带捕获的 lambda 是默认可构造的,因此可以简单地将 lambda 内联的
decltype
作为第二个模板参数传递给std::set
。当然,在这种颠倒自然顺序的特定情况下,
std::greater
更合适。Since C++ 20, lambdas without captures are default constructible, so one can simply pass
decltype
of the lambda inline as the second template parameter tostd::set
.Of course, in this specific case of reversing the natural order,
std::greater
is more appropriate.您可以使用一个小类 lambda_wrapper<> 以低成本包装 lambda。它比 std::function 快得多,因为没有虚函数调用和动态内存分配。
包装器通过推导 lambda 参数列表和返回类型来工作。
You could use a small class lambda_wrapper<>, to wrap a lambda at low costs. Its much more faster than std::function because there are no virtual function call and a dynamic memory alloc.
Wrapper works by deducing the lambda arguments list and return type.
至少在 Microsoft Visual Studio 中(我没有在其他编译器中尝试过),如果您没有捕获任何内容,则该类型似乎是常规函数指针:
In Microsoft Visual Studio at least (I haven't tried this with other compilers), and if you don't capture anything, the type seems to be a regular function pointer: