为什么要把一元加(+)运算符放在C++lambda前面



我发现在C++中,我们可以在lambda函数+[]{}中使用+文章示例:

#include <iostream>
#include <type_traits>
int main()
{
auto funcPtr = +[] {};
static_assert(std::is_same<decltype(funcPtr), void (*)()>::value);
}

lambda 中+符号的主要思想

您可以通过在lambda前面添加+来强制编译器生成lambda作为函数指针,而不是闭包。

但是在lambda中使用"+"有什么优点?你能提供一个例子或把我链接到解释吗?

它不是lambda的一个功能,而more是隐式类型转换的一个特性。

这里发生的事情源于这样一个事实,即无捕获的lambda可以隐式转换为指向与lambda的operator()具有相同签名的函数的指针。+[]{}是一个一元+为非运算的表达式,因此表达式的唯一合法结果是指向函数的指针。

结果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"); 
}  

请注意,您可以对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(*)()>
}

最新更新