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

Why would one want to put a unary plus (+) operator in front of a C++ lambda?

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

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

lambda中+符号的主要思想

You can force the compiler to generate lambda as a function pointer rather than closure by adding + in front of it as above.

但是在 lambda 中使用“+”有什么好处呢?你能举个例子或者link我来解释一下吗?

这不是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"); 
}  

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