简体   繁体   English

为什么 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神栓演示

Why does std::forward not work in the lambda body?为什么std::forward在 lambda 主体中不起作用?


Updated Information:更新信息:

g++ is ok, but clang++ rejects it. g++ 没问题,但是 clang++ 拒绝了。 Who is correct?谁是正确的?

The captures of a lambda are members of the closure class, and the body is operator() const . lambda 的捕获是闭包 class 的成员,主体是operator() const

You are trying to move a data member of a class in a const member function, which is what the compiler error is telling you您正在尝试在const成员 function 中移动 class 的数据成员,这是编译器错误告诉您的

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

Clang is correct to reject it. Clang 拒绝它是正确的。

decltype(fn2) gives the type of fn2 , suppose the lambda closure type is T , then it'll be T . decltype(fn2)给出fn2的类型,假设 lambda 闭包类型是T ,那么它将是T Function-call operator of the lambda is const-qualified, then std::forward<decltype(fn2)>(fn2) fails to be called. lambda 的函数调用运算符是 const 限定的,则std::forward<decltype(fn2)>(fn2)调用失败。 The template argument for std::forward is specified as T explicitly, then std::forward<decltype(fn2)> is supposed to accept T& (and T&& ) as its parameter type, but a const fn2 can't be bound to reference to non-const . std::forward的模板参数明确指定为T ,然后std::forward<decltype(fn2)>应该接受T& (和T&& )作为其参数类型,但const fn2不能绑定到引用到非常量

As the workaround you might mark the lambda as mutable .作为解决方法,您可以将 lambda 标记为mutable

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM