我是模板和lambdas函数的新手,我正在努力理解这段代码中发生了什么:
function<void (const int &)> foo = [&](auto x) {
x = 42;
}
这里,我假设编译器能够从auto
关键字中判断出x
的类型为const int &
。因此,编译器不应该允许赋值x = 42
。
然而,这段代码编译时没有出错,这让我很困惑。为什么编译器允许这样做?编译器实际上为auto
关键字推导了什么?
auto
从不被推导为引用。它总是被演绎成腐朽的类型。
当传递const int &
(或对某种类型T
的任何引用)时,它将被推导为int
(或衰减类型T
)。(或者更准确地说,当传递具有任何值类别的T
类型的表达式时,它将始终推断为衰退的T
类型。表达式类型从不包括引用,而是转换为值类别。)
您仍然可以分配lambda,因为可以从const int&
(或者更准确地说,从类型为const int
的左值表达式)初始化int
。这就是当您调用foo
时会发生的情况。
因此,您在这里为函数内部的局部参数对象赋值。赋值在lambda外部不可见。
如果要推导引用,请使用auto&&
。然而,这将始终推导引用。它也不会衰减类型,因此const
将被保留。