为什么 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([] {});
}
为什么 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();
}();
#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([] {});
}
为什么 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();
}();