提问人:xmllmx 提问时间:12/3/2021 最后编辑:xmllmx 更新时间:12/3/2021 访问量:300
为什么 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([] {});
}
为什么在 lambda 体中不起作用?std::forward
更新信息:
g++ 没问题,但 clang++ 拒绝了它。谁是对的?
答:
5赞
Caleth
12/3/2021
#1
lambda 的捕获是闭包类的成员,正文是 。operator() const
您正在尝试在成员函数中移动类的数据成员,这就是编译器错误告诉您的内容const
note: candidate function template not viable: 1st argument ('const (lambda at <source>:20:7)') would lose const qualifier
评论
0赞
xmllmx
12/3/2021
我的意图是复制,而不是移动,到 ,为什么不在 lambda 正文中?fn2
fn3
std::forward<decltype(fn2)>(fn2)
T const&
0赞
Caleth
12/3/2021
@xmllmx因为它是值捕获,而不是引用捕获
0赞
xmllmx
12/3/2021
我还有问题,请参阅我更新的问题。
0赞
xmllmx
12/3/2021
我认为转发一个常量对象应该产生而不是.T const&
T&&
0赞
Caleth
12/3/2021
@xmllmx它是常量上下文中的可变对象
5赞
songyuanyao
12/3/2021
#2
叮叮当当拒绝它是正确的。
decltype(fn2)
给出的类型是 ,假设 lambda 闭包类型是 ,那么它将是 。lambda 的函数调用运算符是 const 限定的,则无法调用。std::forward
的模板参数被显式指定,然后应该接受 (和 ) 作为其参数类型,但不能绑定到对 non-const 的引用。fn2
T
T
std::forward<decltype(fn2)>(fn2)
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();
}();
评论
2赞
TheScore
12/3/2021
但价值不一。它是如何绑定到的?fn2
T&&
0赞
songyuanyao
12/3/2021
@TheScore 对不起,我忘了提到采用左值引用的重载。
2赞
TheScore
12/3/2021
谢谢你的编辑完美地回答了我的疑问。
评论
typename T