为什么 std::forward 在 lambda 体中不起作用?

Why does std::forward not work in the lambda body?

#include <utility>

void f(auto const& fn1)
{
    {
        auto fn2 = std::forward<decltype(fn1)>(fn1);
        auto fn3 = std::forward<decltype(fn2)>(fn2); // ok
        fn3();
    }

    [fn2 = std::forward<decltype(fn1)>(fn1)]
    {
        auto const fn3 = fn2;
        auto fn4 = std::forward<decltype(fn3)>(fn3); // ok
        fn4();
    
        auto fn5 = std::forward<decltype(fn2)>(fn2); // error
        fn5();
    }();
}

int main()
{
    f([] {});
}

godbolt demo

为什么 std::forward 在 lambda 体中不起作用?


更新信息:

g++ 可以,但 clang++ 拒绝它。谁是正确的?

lambda 的捕获是闭包 class 的成员,主体是 operator() const

您正试图在 const 成员函数中移动 class 的数据成员,这是编译器错误告诉您的内容

note: candidate function template not viable: 1st argument ('const (lambda at <source>:20:7)') would lose const qualifier

Clang 拒绝它是正确的。

decltype(fn2)给出了fn2的类型,假设lambda闭包类型是T,那么就是T。 lambda 的函数调用运算符是 const 限定的,那么 std::forward<decltype(fn2)>(fn2) 将无法调用。 std::forward 的模板参数明确指定为 T,然后 std::forward<decltype(fn2)> 应该接受 T&(和 T&&)作为其参数类型,但是 const fn2 不能绑定到对 非常量.

的引用

作为解决方法,您可以将 lambda 标记为 mutable

[fn2 = std::forward<decltype(fn1)>(fn1)] mutable
{
    auto fn3 = std::forward<decltype(fn2)>(fn2); // fine
    fn3();
}();