我发现在 C++ 中我们可以+在 lambda 函数中使用+[]{}
文章中的示例:
#include <iostream>
#include <type_traits>
int main()
{
auto funcPtr = +[] {};
static_assert(std::is_same<decltype(funcPtr), void (*)()>::value);
}
Run Code Online (Sandbox Code Playgroud)
lambda中+号的主要思想
您可以通过在前面添加 + 来强制编译器将 lambda 生成为函数指针而不是闭包,如上所示。
但是在 lambda 中使用“+”有什么好处呢?您能否提供示例或将我链接到解释?
Swi*_*Pie 11
它不是 lambda 的特性,更多的是隐式类型转换的特性。
发生的情况源于这样一个事实:无捕获 lambda可以隐式转换为指向与 lambda 具有相同签名的函数的指针operator()。+[]{}是一个表达式,其中一元+ 是 no-op ,因此表达式的唯一合法结果是指向函数的指针。
结果auto funcPtr将是指向函数的指针,而不是 lambda 表达式返回的匿名类型的对象实例。在提供的代码中没有太多优势,但在类型无关的代码中可能很重要,例如decltype使用某种表达式的地方。例如
#include <type_traits>
void foo(int);
template<class T>
struct is_foo : std::is_same<T, decltype(&foo)> {};
int main()
{
auto foo1 = +[](int)->void {};
auto foo2 = [](int)->void {};
static_assert(is_foo<decltype(foo1)>::value, "foo1 is not like foo");
static_assert(is_foo<decltype(+foo2)>::value, "+foo2 is not like foo");
static_assert(is_foo<decltype(foo2)>::value, "foo2 is not like foo");
}
Run Code Online (Sandbox Code Playgroud)
请注意,您可以执行相同的操作foo: std::is_same<T, decltype(+foo)> {};
尽管某些平台可能不支持这一点,因为它们本质上可能具有各种具有不同调用约定的函数指针,并且表达式会不明确。
在模板中使用函数指针对抗 lambda 的优点之一可能是减少模板实例化的数量。
template <typename F>
void f(F func) { func(); }
int main()
{
f([](){}); // f<lambda_1>
f([](){}); // f<lambda_2>
f(+[](){}); // f<void(*)()>
f(+[](){}); // f<void(*)()>
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1434 次 |
| 最近记录: |